diff --git a/Dockerfile b/Dockerfile index 5407dc8..dd23c43 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN tar cvfz go-src.tgz src && du -sh * FROM alpine -COPY --from=builder /go/src/github.com/sneak/merp/merp /bin/merp +COPY --from=builder /go/src/github.com/sneak/merp/cmd/merp/merp /bin/merp # put the source in there too for safekeeping COPY --from=builder /go/go-src.tgz /usr/local/src/go-src.tgz diff --git a/Makefile b/Makefile index b6933a7..79e65c8 100644 --- a/Makefile +++ b/Makefile @@ -29,15 +29,15 @@ endif default: run run: build - DEBUG=1 PORT=1111 ./$(APPNAME) + DEBUG=1 PORT=1111 ./cmd/$(APPNAME)/$(APPNAME) -build: ./$(APPNAME) +build: ./cmd/$(APPNAME)/$(APPNAME) -./$(APPNAME): *.go models/*.go - go build -o $@ $(GOFLAGS) . +./cmd/$(APPNAME)/$(APPNAME): *.go models/*.go cmd/*/*.go + cd ./cmd/$(APPNAME) && go build -o ./$(APPNAME) $(GOFLAGS) . clean: - rm $(APPNAME) + rm ./cmd/$(APPNAME)/$(APPNAME) fmt: go fmt *.go diff --git a/logging.go b/cmd/merp/main.go similarity index 63% rename from logging.go rename to cmd/merp/main.go index d42ee83..ce71ced 100644 --- a/logging.go +++ b/cmd/merp/main.go @@ -1,11 +1,38 @@ //3456789112345676892123456789312345678941234567895123456789612345678971234567898 package main -import "os" import "time" +import "os" + import "github.com/rs/zerolog" import "github.com/rs/zerolog/log" import "golang.org/x/crypto/ssh/terminal" +import "github.com/sneak/merp" + +//revive:disable +var Version string +var Buildtime string +var Builduser string +var Buildarch string +var Appname string + +//revive:enable + +func main() { + initLogging() + identify() + merp.ServeForever() +} + +func identify() { + log.Info(). + Str("app", Appname). + Str("version", Version). + Str("buildarch", Buildarch). + Str("buildtime", Buildtime). + Str("builduser", Builduser). + Msg("starting") +} func initLogging() { diff --git a/go.mod b/go.mod index f4c1265..b7a5719 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/mgechev/revive v0.0.0-20191017201419-88015ccf8e97 // indirect github.com/olekukonko/tablewriter v0.0.2 // indirect github.com/rs/zerolog v1.16.0 + github.com/thoas/stats v0.0.0-20190407194641-965cb2de1678 golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd // indirect golang.org/x/tools v0.0.0-20191107185733-c07e1c6ef61c // indirect diff --git a/go.sum b/go.sum index aef9b50..fb6c349 100644 --- a/go.sum +++ b/go.sum @@ -94,6 +94,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= +github.com/thoas/stats v0.0.0-20190407194641-965cb2de1678 h1:kFej3rMKjbzysHYvLmv5iOlbRymDMkNJxbovYb/iP0c= +github.com/thoas/stats v0.0.0-20190407194641-965cb2de1678/go.mod h1:GkZsNBOco11YY68OnXUARbSl26IOXXAeYf6ZKmSZR2M= github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= diff --git a/indexpage.go b/indexpage.go index 270e3ae..78e3af9 100644 --- a/indexpage.go +++ b/indexpage.go @@ -1,4 +1,5 @@ -package main +//3456789112345676892123456789312345678941234567895123456789612345678971234567898 +package merp const basePage = ` diff --git a/main.go b/main.go deleted file mode 100644 index 5e8f3aa..0000000 --- a/main.go +++ /dev/null @@ -1,29 +0,0 @@ -//3456789112345676892123456789312345678941234567895123456789612345678971234567898 -package main - -import "github.com/rs/zerolog/log" - -//revive:disable -var Version string -var Buildtime string -var Builduser string -var Buildarch string -var Appname string - -//revive:enable - -func main() { - initLogging() - identify() - serve() -} - -func identify() { - log.Info(). - Str("app", Appname). - Str("version", Version). - Str("buildarch", Buildarch). - Str("buildtime", Buildtime). - Str("builduser", Builduser). - Msg("starting") -} diff --git a/merp.go b/merp.go index d00574b..d4527e3 100644 --- a/merp.go +++ b/merp.go @@ -1,4 +1,4 @@ -package main +package merp import "encoding/json" import "net/http" @@ -38,7 +38,7 @@ func getLatestMerps() gin.HandlerFunc { c.JSON(http.StatusPreconditionFailed, gin.H{ "this": "failed", "status": http.StatusPreconditionFailed, - "because": "invalid thing format, try a-zA-Z0-9-_", + "because": "invalid thing format, try [a-zA-Z0-9-_]", }) return } @@ -80,7 +80,7 @@ func getLatestMerp() gin.HandlerFunc { c.JSON(http.StatusPreconditionFailed, gin.H{ "this": "failed", "status": http.StatusPreconditionFailed, - "because": "invalid thing format, try a-zA-Z0-9-_", + "because": "invalid thing format, try [a-zA-Z0-9-_]", }) return } @@ -102,7 +102,6 @@ func handleNewMerp() gin.HandlerFunc { // request time thing := c.Param("thing") if ThingRegex.MatchString(thing) == false { - log.Debug().Msgf("%s didnt match", thing) c.JSON(http.StatusPreconditionFailed, gin.H{ "this": "failed", "status": http.StatusPreconditionFailed, @@ -110,7 +109,6 @@ func handleNewMerp() gin.HandlerFunc { }) return } - log.Debug().Msgf("%s matched", thing) //web.Get(`/merp/for/([A-Za-z0-9\-\_\.]+)`, merpHandler) // FIXME rate limit this a bit on thing+clientip+json to cut down on diff --git a/server.go b/server.go index c205734..8181fae 100644 --- a/server.go +++ b/server.go @@ -1,5 +1,5 @@ //3456789112345676892123456789312345678941234567895123456789612345678971234567898 -package main +package merp import "encoding/json" import "fmt" @@ -10,8 +10,9 @@ import "time" //import "github.com/rs/zerolog/log" import "github.com/gin-gonic/gin" import "github.com/dn365/gin-zerolog" +import "github.com/thoas/stats" -func serve() { +func ServeForever() { s := getServer() s.ListenAndServe() } @@ -33,12 +34,23 @@ func getHealthCheckHandler() http.HandlerFunc { } } +func getStatsHandler(middleware *stats.Stats) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + stats := middleware.Data() + b, _ := json.Marshal(stats) + w.Write(b) + } +} + func getRouter() *gin.Engine { if os.Getenv("DEBUG") == "" { gin.SetMode(gin.ReleaseMode) } + statsMiddleware := stats.New() + // empty router r := gin.New() @@ -48,8 +60,15 @@ func getRouter() *gin.Engine { // attach logger middleware r.Use(ginzerolog.Logger("gin")) + r.Use(func(c *gin.Context) { + beginning, recorder := statsMiddleware.Begin(c.Writer) + c.Next() + statsMiddleware.End(beginning, stats.WithRecorder(recorder)) + }) + r.GET("/.well-known/healthcheck.json", gin.WrapF(getHealthCheckHandler())) r.GET("/admin/healthcheck.json", gin.WrapF(getHealthCheckHandler())) + r.GET("/admin/stats.json", gin.WrapF(getStatsHandler(statsMiddleware))) // call it, it returns the appropriate handler function // so we can execute some code at startup time