Skip to content

Commit 8d90cbc

Browse files
author
Zeidan, Omar
committed
Add quantiles to request metrics, correct metric postfix
...the new summary collector will expose the metrics with three names: http_server_requests_seconds(_sum|_count)?, making the former counter metric redundant and making the metric names more consistent with conventions. Leaving in a "legacy" metric collector to avoid breaking existing monitoring and alerting setups that depend on the metric with postfix "_sum_sum".
1 parent 87d35ed commit 8d90cbc

File tree

1 file changed

+23
-18
lines changed

1 file changed

+23
-18
lines changed

web/middleware/requestmetrics/requestmetrics.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,59 @@ package requestmetrics
22

33
import (
44
"fmt"
5-
"github.com/go-chi/chi/v5"
6-
"github.com/go-chi/chi/v5/middleware"
7-
"github.com/prometheus/client_golang/prometheus"
85
"net/http"
96
"strings"
107
"time"
8+
9+
"github.com/go-chi/chi/v5"
10+
"github.com/go-chi/chi/v5/middleware"
11+
"github.com/prometheus/client_golang/prometheus"
1112
)
1213

1314
var (
14-
RequestCounterName = "http_server_requests_seconds_count"
15-
RequestDurationName = "http_server_requests_seconds_sum"
15+
requestSummaryName = "http_server_requests_seconds"
16+
requestSummaryLegacyName = "http_server_requests_seconds_sum"
1617

17-
reqs *prometheus.CounterVec
18-
latency *prometheus.SummaryVec
18+
requestSummary *prometheus.SummaryVec
19+
requestSummaryLegacy *prometheus.SummaryVec
1920
)
2021

2122
func Setup() {
22-
reqs = prometheus.NewCounterVec(
23-
prometheus.CounterOpts{
24-
Name: RequestCounterName,
25-
Help: "Number of incoming HTTP requests processed, partitioned by status code, method and HTTP path (grouped by patterns).",
23+
requestSummary = prometheus.NewSummaryVec(
24+
prometheus.SummaryOpts{
25+
Name: requestSummaryName,
26+
Help: "Request counts, durations, accumulated and in quantiles, partitioned by method, \"outcome\", status code, and HTTP path (grouped by patterns).",
27+
Objectives: map[float64]float64{0.5: 0.05, 0.95: 0.01, 0.99: 0.001},
2628
},
2729
[]string{"method", "outcome", "status", "uri"},
2830
)
29-
prometheus.MustRegister(reqs)
3031

31-
latency = prometheus.NewSummaryVec(
32+
prometheus.MustRegister(requestSummaryLegacy)
33+
34+
requestSummaryLegacy = prometheus.NewSummaryVec(
3235
prometheus.SummaryOpts{
33-
Name: RequestDurationName,
34-
Help: "How long it took to process requests, partitioned by status code, method and HTTP path (grouped by patterns).",
36+
Name: requestSummaryLegacyName,
37+
Help: "(Legacy, replaced by \"http_server_requests_seconds(_sum|_count)?\") Accumulated request durations and counts partitioned by method, \"outcome\", status code, and HTTP path (grouped by patterns).",
3538
},
3639
[]string{"method", "outcome", "status", "uri"},
3740
)
38-
prometheus.MustRegister(latency)
41+
42+
prometheus.MustRegister(requestSummary)
3943
}
4044

4145
func RecordRequestMetrics(next http.Handler) http.Handler {
4246
fn := func(w http.ResponseWriter, r *http.Request) {
4347
start := time.Now()
4448
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
4549
next.ServeHTTP(ww, r)
50+
duration := time.Since(start)
4651

4752
rctx := chi.RouteContext(r.Context())
4853
routePattern := strings.Join(rctx.RoutePatterns, "")
4954
routePattern = strings.Replace(routePattern, "/*/", "/", -1)
5055

51-
reqs.WithLabelValues(r.Method, outcome(ww.Status()), fmt.Sprintf("%d", ww.Status()), routePattern).Inc()
52-
latency.WithLabelValues(r.Method, outcome(ww.Status()), fmt.Sprintf("%d", ww.Status()), routePattern).Observe(float64(time.Since(start).Microseconds()) / 1000000)
56+
requestSummary.WithLabelValues(r.Method, outcome(ww.Status()), fmt.Sprintf("%d", ww.Status()), routePattern).Observe(duration.Seconds())
57+
requestSummaryLegacy.WithLabelValues(r.Method, outcome(ww.Status()), fmt.Sprintf("%d", ww.Status()), routePattern).Observe(duration.Seconds())
5358
}
5459
return http.HandlerFunc(fn)
5560
}

0 commit comments

Comments
 (0)