github.com/lingyao2333/mo-zero@v1.4.1/rest/handler/prometheushandler.go (about)

     1  package handler
     2  
     3  import (
     4  	"net/http"
     5  	"strconv"
     6  	"time"
     7  
     8  	"github.com/lingyao2333/mo-zero/core/metric"
     9  	"github.com/lingyao2333/mo-zero/core/timex"
    10  	"github.com/lingyao2333/mo-zero/rest/internal/response"
    11  )
    12  
    13  const serverNamespace = "http_server"
    14  
    15  var (
    16  	metricServerReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
    17  		Namespace: serverNamespace,
    18  		Subsystem: "requests",
    19  		Name:      "duration_ms",
    20  		Help:      "http server requests duration(ms).",
    21  		Labels:    []string{"path"},
    22  		Buckets:   []float64{5, 10, 25, 50, 100, 250, 500, 1000},
    23  	})
    24  
    25  	metricServerReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{
    26  		Namespace: serverNamespace,
    27  		Subsystem: "requests",
    28  		Name:      "code_total",
    29  		Help:      "http server requests error count.",
    30  		Labels:    []string{"path", "code"},
    31  	})
    32  )
    33  
    34  // PrometheusHandler returns a middleware that reports stats to prometheus.
    35  func PrometheusHandler(path string) func(http.Handler) http.Handler {
    36  	return func(next http.Handler) http.Handler {
    37  		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    38  			startTime := timex.Now()
    39  			cw := &response.WithCodeResponseWriter{Writer: w}
    40  			defer func() {
    41  				metricServerReqDur.Observe(int64(timex.Since(startTime)/time.Millisecond), path)
    42  				metricServerReqCodeTotal.Inc(path, strconv.Itoa(cw.Code))
    43  			}()
    44  
    45  			next.ServeHTTP(cw, r)
    46  		})
    47  	}
    48  }