diff --git a/routing/routes.go b/routing/routes.go index 3611c33da5edfe46787b0526cc13e205da0abd96..72ebb067fe2a42156651e1415b1f24090a9e23bb 100644 --- a/routing/routes.go +++ b/routing/routes.go @@ -25,6 +25,11 @@ func SetRoutes( router *f.App, config *configuration.Config, store state.Store, return err } + metricsTextTemplate, err := template.New( "metrics" ).Parse( metricsText ) + if err != nil { + return err + } + if config.LogLevel == "debug" { router.All( "*", func( c *f.Ctx ) error { log.Printf( "%s %s mime:%s agent:%s", @@ -90,6 +95,35 @@ func SetRoutes( router *f.App, config *configuration.Config, store state.Store, }) + router.Get( "/metrics", func( c *f.Ctx ) error { + headers := c.GetReqHeaders() + acceptHeader := strings.Join( headers[ "Accept" ], " " ) + buffer := &bytes.Buffer{} + + if strings.Contains( acceptHeader , "json" ) { + // FUTUREWORK: implement https://opentelemetry.io/docs/specs/otlp/#otlphttp + return c.SendStatus( http.StatusNotAcceptable ) + } else { + names, err := store.List() + if err != nil { + return c.SendStatus( http.StatusInternalServerError ) + } + + data := metricsTextData{ + Count: len( names ), + } + + err = metricsTextTemplate.Execute( buffer, data ) + if err != nil { + return err + } + + c.Set( "Content-Type", "text/plain; charset=utf-8" ) + return c.Send( buffer.Bytes() ) + } + }) + + router.Get( "/env", func( c *f.Ctx ) error { c.Type( "txt", "utf-8" ) diff --git a/routing/templates.go b/routing/templates.go index 5e06f2960d8d134c37b76c371cfeb3965f5d793f..dd99caa793b122d96d106f2547af455392c1df02 100644 --- a/routing/templates.go +++ b/routing/templates.go @@ -20,3 +20,14 @@ type indexHtmlData struct { Version string Color string } + + +const metricsText = ` + # HELP state_entries_quantity The current number of state entries being stored + # TYPE state_entries_quantity gauge + state_entries_quantity {{ .Count }} +` + +type metricsTextData struct { + Count int +}