@marcel91200 / caddy Mirror · read-only / commits / f197cec7
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

metrics: Always track method label in uppercase (#3742)

* metrics: Always track method label in uppercase Signed-off-by: Dave Henderson <dhenderson@gmail.com> * Just use strings.ToUpper for clarity Signed-off-by: Dave Henderson <dhenderson@gmail.com>

Dave Henderson committed Sep 22, 2020 at 22:10 UTC f197cec7f3a599ca18807e7b7719ef7666cfdb70
3 files changed +52 -5
admin.go
+2 -3
@@ -36,7 +36,6 @@ import (
36 "time"
37
38 "github.com/prometheus/client_golang/prometheus"
39 - "github.com/prometheus/client_golang/prometheus/promhttp"
39 "go.uber.org/zap"
40 )
41
@@ -111,7 +110,7 @@ func (admin AdminConfig) newAdminHandler(addr NetworkAddress) adminHandler {
110
111 addRouteWithMetrics := func(pattern string, handlerLabel string, h http.Handler) {
112 labels := prometheus.Labels{"path": pattern, "handler": handlerLabel}
114 - h = promhttp.InstrumentHandlerCounter(
113 + h = instrumentHandlerCounter(
114 adminMetrics.requestCount.MustCurryWith(labels),
115 h,
116 )
@@ -126,7 +125,7 @@ func (admin AdminConfig) newAdminHandler(addr NetworkAddress) adminHandler {
125 labels := prometheus.Labels{
126 "path": pattern,
127 "handler": handlerLabel,
129 - "method": r.Method,
128 + "method": strings.ToUpper(r.Method),
129 }
130 adminMetrics.requestErrors.With(labels).Inc()
131 }
metrics.go
+45
@@ -1,6 +1,10 @@
1 package caddy
2
3 import (
4 + "net/http"
5 + "strconv"
6 + "strings"
7 +
8 "github.com/prometheus/client_golang/prometheus"
9 "github.com/prometheus/client_golang/prometheus/promauto"
10 )
@@ -30,3 +34,44 @@ var adminMetrics = struct {
34 requestCount *prometheus.CounterVec
35 requestErrors *prometheus.CounterVec
36 }{}
37 +
38 +// Similar to promhttp.InstrumentHandlerCounter, but upper-cases method names
39 +// instead of lower-casing them.
40 +//
41 +// Unlike promhttp.InstrumentHandlerCounter, this assumes a "code" and "method"
42 +// label is present, and will panic otherwise.
43 +func instrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc {
44 + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
45 + d := newDelegator(w)
46 + next.ServeHTTP(d, r)
47 + counter.With(prometheus.Labels{
48 + "code": sanitizeCode(d.status),
49 + "method": strings.ToUpper(r.Method),
50 + }).Inc()
51 + })
52 +}
53 +
54 +func newDelegator(w http.ResponseWriter) *delegator {
55 + return &delegator{
56 + ResponseWriter: w,
57 + }
58 +}
59 +
60 +type delegator struct {
61 + http.ResponseWriter
62 + status int
63 +}
64 +
65 +func (d *delegator) WriteHeader(code int) {
66 + d.status = code
67 + d.ResponseWriter.WriteHeader(code)
68 +}
69 +
70 +func sanitizeCode(s int) string {
71 + switch s {
72 + case 0, 200:
73 + return "200"
74 + default:
75 + return strconv.Itoa(s)
76 + }
77 +}
modules/caddyhttp/metrics.go
+5 -2
@@ -4,6 +4,7 @@ import (
4 "context"
5 "net/http"
6 "strconv"
7 + "strings"
8 "sync"
9 "time"
10
@@ -108,7 +109,10 @@ func newMetricsInstrumentedHandler(handler string, mh MiddlewareHandler) *metric
109 func (h *metricsInstrumentedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request, next Handler) error {
110 server := serverNameFromContext(r.Context())
111 labels := prometheus.Labels{"server": server, "handler": h.handler}
111 - statusLabels := prometheus.Labels{"server": server, "handler": h.handler, "method": r.Method, "code": ""}
112 + method := strings.ToUpper(r.Method)
113 + // the "code" value is set later, but initialized here to eliminate the possibility
114 + // of a panic
115 + statusLabels := prometheus.Labels{"server": server, "handler": h.handler, "method": method, "code": ""}
116
117 inFlight := httpMetrics.requestInFlight.With(labels)
118 inFlight.Inc()
@@ -154,7 +158,6 @@ func sanitizeCode(code int) string {
158 return "200"
159 }
160 return strconv.Itoa(code)
157 -
161 }
162
163 // taken from https://github.com/prometheus/client_golang/blob/6007b2b5cae01203111de55f753e76d8dac1f529/prometheus/promhttp/instrument_server.go#L298