Repository: zeromicro/go-zero
Pull request #3226 (2023-05-08 10:32:57)

Add method label for prometheus middleware metrics
Add 'method' label for prometheus middleware metrics to resolve issue #3076

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/zeromicro/go-zero/pull/3226?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#3226](https://app.codecov.io/gh/zeromicro/go-zero/pull/3226?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (d4b9507) into [master](https://app.codecov.io/gh/zeromicro/go-zero/commit/9f42eda9ffefbc1e6b3183bc8a1efc94f7cc2b71?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (9f42eda) will **not change** coverage.
> The diff coverage is `100.00%`.


| [Impacted Files](https://app.codecov.io/gh/zeromicro/go-zero/pull/3226?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [rest/engine.go](https://app.codecov.io/gh/zeromicro/go-zero/pull/3226?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmVzdC9lbmdpbmUuZ28=) | `93.88% <100.00%> (ø)` | |
| [rest/handler/prometheushandler.go](https://app.codecov.io/gh/zeromicro/go-zero/pull/3226?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cmVzdC9oYW5kbGVyL3Byb21ldGhldXNoYW5kbGVyLmdv) | `100.00% <100.00%> (ø)` | |


Patch:
diff --git a/rest/engine.go b/rest/engine.go
index 5f2ffd91..a206b3ce 100644
--- a/rest/engine.go
+++ b/rest/engine.go
@@ -136,7 +136,7 @@ func (ng *engine) buildChainWithNativeMiddlewares(fr featuredRoutes, route Route
 		chn = chn.Append(ng.getLogHandler())
 	}
 	if ng.conf.Middlewares.Prometheus {
-		chn = chn.Append(handler.PrometheusHandler(route.Path))
+		chn = chn.Append(handler.PrometheusHandler(route.Path, route.Method))
 	}
 	if ng.conf.Middlewares.MaxConns {
 		chn = chn.Append(handler.MaxConnsHandler(ng.conf.MaxConns))
diff --git a/rest/handler/prometheushandler.go b/rest/handler/prometheushandler.go
index fcafa0a1..c1aa7ae7 100644
--- a/rest/handler/prometheushandler.go
+++ b/rest/handler/prometheushandler.go
@@ -18,7 +18,7 @@ var (
 		Subsystem: "requests",
 		Name:      "duration_ms",
 		Help:      "http server requests duration(ms).",
-		Labels:    []string{"path"},
+		Labels:    []string{"path", "method"},
 		Buckets:   []float64{5, 10, 25, 50, 100, 250, 500, 1000},
 	})
 
@@ -27,19 +27,19 @@ var (
 		Subsystem: "requests",
 		Name:      "code_total",
 		Help:      "http server requests error count.",
-		Labels:    []string{"path", "code"},
+		Labels:    []string{"path", "code", "method"},
 	})
 )
 
 // PrometheusHandler returns a middleware that reports stats to prometheus.
-func PrometheusHandler(path string) func(http.Handler) http.Handler {
+func PrometheusHandler(path, method string) func(http.Handler) http.Handler {
 	return func(next http.Handler) http.Handler {
 		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 			startTime := timex.Now()
 			cw := &response.WithCodeResponseWriter{Writer: w}
 			defer func() {
-				metricServerReqDur.Observe(int64(timex.Since(startTime)/time.Millisecond), path)
-				metricServerReqCodeTotal.Inc(path, strconv.Itoa(cw.Code))
+				metricServerReqDur.Observe(int64(timex.Since(startTime)/time.Millisecond), path, method)
+				metricServerReqCodeTotal.Inc(path, strconv.Itoa(cw.Code), method)
 			}()
 
 			next.ServeHTTP(cw, r)


Test patch:
diff --git a/rest/handler/prometheushandler_test.go b/rest/handler/prometheushandler_test.go
index ce7551e8..c0c1dec2 100644
--- a/rest/handler/prometheushandler_test.go
+++ b/rest/handler/prometheushandler_test.go
@@ -10,7 +10,7 @@ import (
 )
 
 func TestPromMetricHandler_Disabled(t *testing.T) {
-	promMetricHandler := PrometheusHandler("/user/login")
+	promMetricHandler := PrometheusHandler("/user/login", http.MethodGet)
 	handler := promMetricHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusOK)
 	}))
@@ -26,7 +26,7 @@ func TestPromMetricHandler_Enabled(t *testing.T) {
 		Host: "localhost",
 		Path: "/",
 	})
-	promMetricHandler := PrometheusHandler("/user/login")
+	promMetricHandler := PrometheusHandler("/user/login", http.MethodGet)
 	handler := promMetricHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusOK)
 	}))