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: Fix panic when headers aren't written (#3737)
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Dave Henderson committed
Sep 21, 2020 at 15:42 UTC
b1d456d8abf15616afb6c6893af90473b4941365
2 files changed
+27
-1
modules/caddyhttp/metrics.go
+9
-1
@@ -108,7 +108,7 @@ func newMetricsInstrumentedHandler(handler string, mh MiddlewareHandler) *metric
108
func (h *metricsInstrumentedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request, next Handler) error {
109
server := serverNameFromContext(r.Context())
110
labels := prometheus.Labels{"server": server, "handler": h.handler}
111
- statusLabels := prometheus.Labels{"server": server, "handler": h.handler, "method": r.Method}
111
+ statusLabels := prometheus.Labels{"server": server, "handler": h.handler, "method": r.Method, "code": ""}
112
113
inFlight := httpMetrics.requestInFlight.With(labels)
114
inFlight.Inc()
@@ -134,6 +134,14 @@ func (h *metricsInstrumentedHandler) ServeHTTP(w http.ResponseWriter, r *http.Re
134
return err
135
}
136
137
+ // If the code hasn't been set yet, and we didn't encounter an error, we're
138
+ // probably falling through with an empty handler.
139
+ if statusLabels["code"] == "" {
140
+ // we still sanitize it, even though it's likely to be 0. A 200 is
141
+ // returned on fallthrough so we want to reflect that.
142
+ statusLabels["code"] = sanitizeCode(wrec.Status())
143
+ }
144
+
145
httpMetrics.requestDuration.With(statusLabels).Observe(dur)
146
httpMetrics.requestSize.With(statusLabels).Observe(float64(computeApproximateRequestSize(r)))
147
httpMetrics.responseSize.With(statusLabels).Observe(float64(wrec.Size()))
modules/caddyhttp/metrics_test.go
+18
@@ -57,6 +57,24 @@ func TestMetricsInstrumentedHandler(t *testing.T) {
57
if err := ih.ServeHTTP(w, r, h); err != nil {
58
t.Errorf("Received unexpected error: %w", err)
59
}
60
+
61
+ // an empty handler - no errors, no header written
62
+ mh = middlewareHandlerFunc(func(w http.ResponseWriter, r *http.Request, h Handler) error {
63
+ return nil
64
+ })
65
+ ih = newMetricsInstrumentedHandler("empty", mh)
66
+ r = httptest.NewRequest("GET", "/", nil)
67
+ w = httptest.NewRecorder()
68
+
69
+ if err := ih.ServeHTTP(w, r, h); err != nil {
70
+ t.Errorf("Received unexpected error: %w", err)
71
+ }
72
+ if actual := w.Result().StatusCode; actual != 200 {
73
+ t.Errorf("Not same: expected status code %#v, but got %#v", 200, actual)
74
+ }
75
+ if actual := w.Result().Header; len(actual) != 0 {
76
+ t.Errorf("Not empty: expected headers to be empty, but got %#v", actual)
77
+ }
78
}
79
80
type middlewareHandlerFunc func(http.ResponseWriter, *http.Request, Handler) error