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