|
| 1 | +# Usage |
| 2 | + |
| 3 | +``` |
| 4 | +package main |
| 5 | +
|
| 6 | +import ( |
| 7 | + "github.com/labstack/echo/v4" |
| 8 | + "github.com/labstack/echo-contrib/prometheus/echoprometheus" |
| 9 | +) |
| 10 | +
|
| 11 | +func main() { |
| 12 | + e := echo.New() |
| 13 | + // Enable metrics middleware |
| 14 | + e.Use(echoprometheus.NewMiddleware("myapp")) |
| 15 | + e.GET("/metrics", echoprometheus.NewHandler()) |
| 16 | +
|
| 17 | + e.Logger.Fatal(e.Start(":1323")) |
| 18 | +} |
| 19 | +``` |
| 20 | + |
| 21 | + |
| 22 | +# How to migrate |
| 23 | + |
| 24 | +## Creating and adding middleware to the application |
| 25 | + |
| 26 | +Older `prometheus` middleware |
| 27 | +```go |
| 28 | + e := echo.New() |
| 29 | + p := prometheus.NewPrometheus("echo", nil) |
| 30 | + p.Use(e) |
| 31 | +``` |
| 32 | + |
| 33 | +With the new `echoprometheus` middleware |
| 34 | +```go |
| 35 | + e := echo.New() |
| 36 | + e.Use(echoprometheus.NewMiddleware("myapp")) // register middleware to gather metrics from requests |
| 37 | + e.GET("/metrics", echoprometheus.NewHandler()) // register route to serve gathered metrics in Prometheus format |
| 38 | +``` |
| 39 | + |
| 40 | +## Replacement for `Prometheus.MetricsList` field, `NewMetric(m *Metric, subsystem string)` function and `prometheus.Metric` struct |
| 41 | + |
| 42 | +The `NewMetric` function allowed to create custom metrics with the old `prometheus` middleware. This helper is no longer available |
| 43 | +to avoid the added complexity. It is recommended to use native Prometheus metrics and register those yourself. |
| 44 | + |
| 45 | +This can be done now as follows: |
| 46 | +```go |
| 47 | + e := echo.New() |
| 48 | + |
| 49 | + customRegistry := prometheus.NewRegistry() // create custom registry for your custom metrics |
| 50 | + customCounter := prometheus.NewCounter( // create new counter metric. This is replacement for `prometheus.Metric` struct |
| 51 | + prometheus.CounterOpts{ |
| 52 | + Name: "custom_requests_total", |
| 53 | + Help: "How many HTTP requests processed, partitioned by status code and HTTP method.", |
| 54 | + }, |
| 55 | + ) |
| 56 | + if err := customRegistry.Register(customCounter); err != nil { // register your new counter metric with metrics registry |
| 57 | + log.Fatal(err) |
| 58 | + } |
| 59 | + |
| 60 | + e.Use(NewMiddlewareWithConfig(MiddlewareConfig{ |
| 61 | + AfterNext: func(c echo.Context, err error) { |
| 62 | + customCounter.Inc() // use our custom metric in middleware. after every request increment the counter |
| 63 | + }, |
| 64 | + Registerer: customRegistry, // use our custom registry instead of default Prometheus registry |
| 65 | + })) |
| 66 | + e.GET("/metrics", NewHandlerWithConfig(HandlerConfig{Gatherer: customRegistry})) // register route for getting gathered metrics data from our custom Registry |
| 67 | +``` |
| 68 | + |
| 69 | +## Replacement for `Prometheus.MetricsPath` |
| 70 | + |
| 71 | +`MetricsPath` was used to skip metrics own route from Prometheus metrics. Skipping is no longer done and requests to Prometheus |
| 72 | +route will be included in gathered metrics. |
| 73 | + |
| 74 | +To restore the old behaviour the `/metrics` path needs to be excluded from counting using the Skipper function: |
| 75 | +```go |
| 76 | +conf := echoprometheus.MiddlewareConfig{ |
| 77 | + Skipper: func(c echo.Context) bool { |
| 78 | + return c.Path() == "/metrics" |
| 79 | + }, |
| 80 | +} |
| 81 | +e.Use(echoprometheus.NewMiddlewareWithConfig(conf)) |
| 82 | +``` |
| 83 | + |
| 84 | +## Replacement for `Prometheus.RequestCounterURLLabelMappingFunc` and `Prometheus.RequestCounterHostLabelMappingFunc` |
| 85 | + |
| 86 | +These function fields were used to define how "URL" or "Host" attribute in Prometheus metric lines are created. |
| 87 | + |
| 88 | +These can now be substituted by using `LabelFuncs`: |
| 89 | +```go |
| 90 | + e.Use(echoprometheus.NewMiddlewareWithConfig(echoprometheus.MiddlewareConfig{ |
| 91 | + LabelFuncs: map[string]echoprometheus.LabelValueFunc{ |
| 92 | + "scheme": func(c echo.Context, err error) string { // additional custom label |
| 93 | + return c.Scheme() |
| 94 | + }, |
| 95 | + "url": func(c echo.Context, err error) string { // overrides default 'url' label value |
| 96 | + return "x_" + c.Request().URL.Path |
| 97 | + }, |
| 98 | + "host": func(c echo.Context, err error) string { // overrides default 'host' label value |
| 99 | + return "y_" + c.Request().Host |
| 100 | + }, |
| 101 | + }, |
| 102 | + })) |
| 103 | +``` |
| 104 | + |
| 105 | +Will produce Prometheus line as |
| 106 | +`echo_request_duration_seconds_count{code="200",host="y_example.com",method="GET",scheme="http",url="x_/ok",scheme="http"} 1` |
| 107 | + |
| 108 | + |
| 109 | +## Replacement for `Metric.Buckets` and modifying default metrics |
| 110 | + |
| 111 | +The `echoprometheus` middleware registers the following metrics by default: |
| 112 | + |
| 113 | +* Counter `requests_total` |
| 114 | +* Histogram `request_duration_seconds` |
| 115 | +* Histogram `response_size_bytes` |
| 116 | +* Histogram `request_size_bytes` |
| 117 | + |
| 118 | +You can modify their definition before these metrics are registed with `CounterOptsFunc` and `HistogramOptsFunc` callbacks |
| 119 | + |
| 120 | +Example: |
| 121 | +```go |
| 122 | + e.Use(NewMiddlewareWithConfig(MiddlewareConfig{ |
| 123 | + HistogramOptsFunc: func(opts prometheus.HistogramOpts) prometheus.HistogramOpts { |
| 124 | + if opts.Name == "request_duration_seconds" { |
| 125 | + opts.Buckets = []float64{1.0 * bKB, 2.0 * bKB, 5.0 * bKB, 10.0 * bKB, 100 * bKB, 500 * bKB, 1.0 * bMB, 2.5 * bMB, 5.0 * bMB, 10.0 * bMB} |
| 126 | + } |
| 127 | + return opts |
| 128 | + }, |
| 129 | + CounterOptsFunc: func(opts prometheus.CounterOpts) prometheus.CounterOpts { |
| 130 | + if opts.Name == "requests_total" { |
| 131 | + opts.ConstLabels = prometheus.Labels{"my_const": "123"} |
| 132 | + } |
| 133 | + return opts |
| 134 | + }, |
| 135 | + })) |
| 136 | +``` |
| 137 | + |
| 138 | +## Replacement for `PushGateway` struct and related methods |
| 139 | + |
| 140 | +Function `RunPushGatewayGatherer` starts pushing collected metrics and block until context completes or ErrorHandler returns an error. |
| 141 | +This function should be run in separate goroutine. |
| 142 | + |
| 143 | +Example: |
| 144 | +```go |
| 145 | + go func() { |
| 146 | + config := echoprometheus.PushGatewayConfig{ |
| 147 | + PushGatewayURL: "https://host:9080", |
| 148 | + PushInterval: 10 * time.Millisecond, |
| 149 | + } |
| 150 | + if err := echoprometheus.RunPushGatewayGatherer(context.Background(), config); !errors.Is(err, context.Canceled) { |
| 151 | + log.Fatal(err) |
| 152 | + } |
| 153 | + }() |
| 154 | +``` |
0 commit comments