diff --git a/README.md b/README.md index eec2568..717688b 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,16 @@ package main import ( "net/http" + echoPrometheus "github.com/globocom/echo-prometheus/v2" "github.com/labstack/echo/v4" "github.com/prometheus/client_golang/prometheus/promhttp" - echoPrometheus "github.com/globocom/echo-prometheus" ) func main() { e := echo.New() - e.Use(echoPrometheus.MetricsMiddleware()) + ec := echoPrometheus.MetricsMiddleware() + e.Use(ec.MetricsMiddlewareFunc()) e.GET("/metrics", echo.WrapHandler(promhttp.Handler())) e.GET("/", func(c echo.Context) error { @@ -36,29 +37,22 @@ package main import ( "net/http" + echoPrometheus "github.com/globocom/echo-prometheus/v2" "github.com/labstack/echo/v4" "github.com/prometheus/client_golang/prometheus/promhttp" - echoPrometheus "github.com/globocom/echo-prometheus" ) func main() { e := echo.New() - var configMetrics = echoPrometheus.NewConfig() - configMetrics.Namespace = "namespace" - configMetrics.Buckets = []float64{ - 0.0005, // 0.5ms - 0.001, // 1ms - 0.005, // 5ms - 0.01, // 10ms - 0.05, // 50ms - 0.1, // 100ms - 0.5, // 500ms - 1, // 1s - 2, // 2s - } - - e.Use(echoPrometheus.MetricsMiddlewareWithConfig(configMetrics)) + ec := echoPrometheus.MetricsMiddleware() + ec. + WithBuckets([]float64{0.01, 0.1, 0.5, 1.0, 5.0, 10.0}). + WithNormalizeHTTPStatus(true). + WithNamespace("my_custom_namespace"). + WithSubsystem("my_custom_subsystem") + + e.Use(ec.MetricsMiddlewareFunc()) e.GET("/metrics", echo.WrapHandler(promhttp.Handler())) e.GET("/", func(c echo.Context) error { diff --git a/example/customConfig/main.go b/example/customConfig/main.go index b4a1fae..82cc835 100644 --- a/example/customConfig/main.go +++ b/example/customConfig/main.go @@ -3,7 +3,7 @@ package main import ( "net/http" - echoPrometheus "github.com/globocom/echo-prometheus" + echoPrometheus "github.com/globocom/echo-prometheus/v2" "github.com/labstack/echo/v4" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -11,22 +11,14 @@ import ( func main() { e := echo.New() - var configMetrics = echoPrometheus.NewConfig() - configMetrics.Namespace = "namespace" - configMetrics.NormalizeHTTPStatus = false - configMetrics.Buckets = []float64{ - 0.0005, // 0.5ms - 0.001, // 1ms - 0.005, // 5ms - 0.01, // 10ms - 0.05, // 50ms - 0.1, // 100ms - 0.5, // 500ms - 1, // 1s - 2, // 2s - } + ec := echoPrometheus.MetricsMiddleware() + ec. + WithBuckets([]float64{0.01, 0.1, 0.5, 1.0, 5.0, 10.0}). + WithNormalizeHTTPStatus(true). + WithNamespace("MyCustomNamespace"). + WithSubsystem("MyCustomSubsystem") - e.Use(echoPrometheus.MetricsMiddlewareWithConfig(configMetrics)) + e.Use(ec.MetricsMiddlewareFunc()) e.GET("/metrics", echo.WrapHandler(promhttp.Handler())) e.GET("/", func(c echo.Context) error { diff --git a/example/defaultConfig/main.go b/example/defaultConfig/main.go index bd85b18..d7bc1a0 100644 --- a/example/defaultConfig/main.go +++ b/example/defaultConfig/main.go @@ -3,7 +3,7 @@ package main import ( "net/http" - echoPrometheus "github.com/globocom/echo-prometheus" + echoPrometheus "github.com/globocom/echo-prometheus/v2" "github.com/labstack/echo/v4" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -11,7 +11,8 @@ import ( func main() { e := echo.New() - e.Use(echoPrometheus.MetricsMiddleware()) + ec := echoPrometheus.MetricsMiddleware() + e.Use(ec.MetricsMiddlewareFunc()) e.GET("/metrics", echo.WrapHandler(promhttp.Handler())) e.GET("/", func(c echo.Context) error { diff --git a/go.mod b/go.mod index a18633c..135b219 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/globocom/echo-prometheus +module github.com/globocom/echo-prometheus/v2 go 1.12 diff --git a/middleware.go b/middleware.go index eee508c..169e3cb 100644 --- a/middleware.go +++ b/middleware.go @@ -1,8 +1,8 @@ package echoprometheus import ( - "strconv" "reflect" + "strconv" echo "github.com/labstack/echo/v4" "github.com/prometheus/client_golang/prometheus" @@ -11,9 +11,9 @@ import ( // Config responsible to configure middleware type Config struct { - Namespace string - Buckets []float64 - Subsystem string + Namespace string + Buckets []float64 + Subsystem string NormalizeHTTPStatus bool } @@ -23,6 +23,10 @@ const ( notFoundPath = "/not-found" ) +type EchoPrometheus struct { + config Config +} + // DefaultConfig has the default instrumentation config var DefaultConfig = Config{ Namespace: "echo", @@ -66,32 +70,45 @@ func isNotFoundHandler(handler echo.HandlerFunc) bool { return reflect.ValueOf(handler).Pointer() == reflect.ValueOf(echo.NotFoundHandler).Pointer() } -// NewConfig returns a new config with default values -func NewConfig() Config { - return DefaultConfig +// WithNamespace change the namespace +func (ep *EchoPrometheus) WithNamespace(namespace string) *EchoPrometheus { + ep.config.Namespace = namespace + return ep } -// MetricsMiddleware returns an echo middleware with default config for instrumentation. -func MetricsMiddleware() echo.MiddlewareFunc { - return MetricsMiddlewareWithConfig(DefaultConfig) +// WithBuckets change the buckets +func (ep *EchoPrometheus) WithBuckets(buckets []float64) *EchoPrometheus { + ep.config.Buckets = buckets + return ep } -// MetricsMiddlewareWithConfig returns an echo middleware for instrumentation. -func MetricsMiddlewareWithConfig(config Config) echo.MiddlewareFunc { +// WithSubsystem change the subsystem +func (ep *EchoPrometheus) WithSubsystem(subsystem string) *EchoPrometheus { + ep.config.Subsystem = subsystem + return ep +} +// WithNormalizeHTTPStatus change the normalizeHTTPStatus flag +func (ep *EchoPrometheus) WithNormalizeHTTPStatus(normalizeHTTPStatus bool) *EchoPrometheus { + ep.config.NormalizeHTTPStatus = normalizeHTTPStatus + return ep +} + +// MetricsMiddlewareWithConfig returns an echo middleware for instrumentation. +func (ep EchoPrometheus) MetricsMiddlewareFunc() echo.MiddlewareFunc { httpRequests := promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: config.Namespace, - Subsystem: config.Subsystem, + Namespace: ep.config.Namespace, + Subsystem: ep.config.Subsystem, Name: httpRequestsCount, Help: "Number of HTTP operations", }, []string{"status", "method", "handler"}) httpDuration := promauto.NewHistogramVec(prometheus.HistogramOpts{ - Namespace: config.Namespace, - Subsystem: config.Subsystem, + Namespace: ep.config.Namespace, + Subsystem: ep.config.Subsystem, Name: httpRequestsDuration, Help: "Spend time by processing a route", - Buckets: config.Buckets, + Buckets: ep.config.Buckets, }, []string{"method", "handler"}) return func(next echo.HandlerFunc) echo.HandlerFunc { @@ -113,7 +130,7 @@ func MetricsMiddlewareWithConfig(config Config) echo.MiddlewareFunc { } status := "" - if config.NormalizeHTTPStatus { + if ep.config.NormalizeHTTPStatus { status = normalizeHTTPStatus(c.Response().Status) } else { status = strconv.Itoa(c.Response().Status) @@ -125,3 +142,10 @@ func MetricsMiddlewareWithConfig(config Config) echo.MiddlewareFunc { } } } + +// MetricsMiddleware returns an echo middleware with default config for instrumentation. +func MetricsMiddleware() *EchoPrometheus { + return &EchoPrometheus{ + config: DefaultConfig, + } +}