From d7f38dfddee25b8836eb22080977dc59daf3a93c Mon Sep 17 00:00:00 2001 From: Simon Pasquier Date: Wed, 19 Jun 2019 17:56:04 +0200 Subject: [PATCH] web: add 'code' label to HTTP metrics (#5640) * web: add prometheus_http_requests_total metrics Signed-off-by: Simon Pasquier * Add unit test for requestCounter metric Signed-off-by: Simon Pasquier --- web/web.go | 22 ++++++++++++++++------ web/web_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/web/web.go b/web/web.go index 4b1f8ef6f..ba2af44de 100644 --- a/web/web.go +++ b/web/web.go @@ -90,6 +90,13 @@ func withStackTracer(h http.Handler, l log.Logger) http.Handler { } var ( + requestCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "prometheus_http_requests_total", + Help: "Counter of HTTP requests.", + }, + []string{"handler", "code"}, + ) requestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "prometheus_http_request_duration_seconds", @@ -109,7 +116,7 @@ var ( ) func init() { - prometheus.MustRegister(requestDuration, responseSize) + prometheus.MustRegister(requestCounter, requestDuration, responseSize) } // Handler serves various HTTP endpoints of the Prometheus server @@ -199,11 +206,14 @@ func instrumentHandlerWithPrefix(prefix string) func(handlerName string, handler } func instrumentHandler(handlerName string, handler http.HandlerFunc) http.HandlerFunc { - return promhttp.InstrumentHandlerDuration( - requestDuration.MustCurryWith(prometheus.Labels{"handler": handlerName}), - promhttp.InstrumentHandlerResponseSize( - responseSize.MustCurryWith(prometheus.Labels{"handler": handlerName}), - handler, + return promhttp.InstrumentHandlerCounter( + requestCounter.MustCurryWith(prometheus.Labels{"handler": handlerName}), + promhttp.InstrumentHandlerDuration( + requestDuration.MustCurryWith(prometheus.Labels{"handler": handlerName}), + promhttp.InstrumentHandlerResponseSize( + responseSize.MustCurryWith(prometheus.Labels{"handler": handlerName}), + handler, + ), ), ) } diff --git a/web/web_test.go b/web/web_test.go index 06115aaa0..f6975bc07 100644 --- a/web/web_test.go +++ b/web/web_test.go @@ -21,10 +21,13 @@ import ( "net/http/httptest" "net/url" "os" + "strconv" "strings" "testing" "time" + prom_testutil "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/notifier" "github.com/prometheus/prometheus/rules" @@ -402,3 +405,31 @@ func TestDebugHandler(t *testing.T) { testutil.Equals(t, tc.code, w.Code) } } + +func TestHTTPMetrics(t *testing.T) { + t.Parallel() + + handler := New(nil, &Options{RoutePrefix: "/"}) + getReady := func() int { + t.Helper() + w := httptest.NewRecorder() + + req, err := http.NewRequest("GET", "/-/ready", nil) + testutil.Ok(t, err) + + handler.router.ServeHTTP(w, req) + return w.Code + } + + code := getReady() + testutil.Equals(t, http.StatusServiceUnavailable, code) + testutil.Equals(t, 1, int(prom_testutil.ToFloat64(requestCounter.WithLabelValues("/-/ready", strconv.Itoa(http.StatusServiceUnavailable))))) + + handler.Ready() + for range [2]int{} { + code = getReady() + testutil.Equals(t, http.StatusOK, code) + } + testutil.Equals(t, 2, int(prom_testutil.ToFloat64(requestCounter.WithLabelValues("/-/ready", strconv.Itoa(http.StatusOK))))) + testutil.Equals(t, 1, int(prom_testutil.ToFloat64(requestCounter.WithLabelValues("/-/ready", strconv.Itoa(http.StatusServiceUnavailable))))) +}