package metrics import ( "net/http" "strconv" "time" "github.com/go-chi/chi/v5/middleware" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" ) var ( reg = prometheus.NewRegistry() // http 请求总量 httpRequestsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ Name: "http_requests_total", Help: "Counter of HTTP requests to prime", }, []string{"handler", "method", "code"}) // http 请求耗时 httpRequestDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Histogram of latencies for HTTP requests to prime.", Buckets: []float64{0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1}, }, []string{"handler", "method", "code"}) ) func init() { reg.MustRegister( collectors.NewGoCollector(), collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), ) reg.MustRegister(httpRequestsTotal) reg.MustRegister(httpRequestDuration) } // Handler func Handler() http.HandlerFunc { return promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}).ServeHTTP } // collectHTTPRequestMetric http metrics 处理 func collectHTTPRequestMetric(handler, method, code string, duration time.Duration) { httpRequestsTotal.WithLabelValues(handler, method, code).Inc() httpRequestDuration.WithLabelValues(handler, method, code).Observe(duration.Seconds()) } // RequestCollect func RequestCollect(name string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor) t1 := time.Now() defer func() { collectHTTPRequestMetric(name, r.Method, strconv.Itoa(ww.Status()), time.Since(t1)) }() next.ServeHTTP(ww, r) } return http.HandlerFunc(fn) } }