mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
58 lines
1.7 KiB
Go
58 lines
1.7 KiB
Go
package http
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/go-chi/chi/middleware"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
// Middleware is a handler that exposes prometheus metrics for the number of requests,
|
|
// the latency and the response size, partitioned by status code, method and HTTP path.
|
|
type metrics struct {
|
|
reqs *prometheus.CounterVec
|
|
latency *prometheus.HistogramVec
|
|
}
|
|
|
|
// NewMiddleware returns a new prometheus Middleware handler.
|
|
func middlewareMetrics(next http.Handler) http.Handler {
|
|
var m metrics
|
|
|
|
m.reqs = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "requests_total",
|
|
Namespace: "neko",
|
|
Subsystem: "http",
|
|
Help: "How many HTTP requests processed, partitioned by status code, method and HTTP path.",
|
|
},
|
|
[]string{"code", "method", "path"},
|
|
)
|
|
prometheus.MustRegister(m.reqs)
|
|
|
|
m.latency = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
|
Name: "request_duration_milliseconds",
|
|
Namespace: "neko",
|
|
Subsystem: "http",
|
|
Help: "How long it took to process the request, partitioned by status code, method and HTTP path.",
|
|
Buckets: []float64{300, 1200, 5000},
|
|
},
|
|
[]string{"code", "method", "path"},
|
|
)
|
|
|
|
prometheus.MustRegister(m.latency)
|
|
return m.handler(next)
|
|
}
|
|
|
|
func (c metrics) handler(next http.Handler) http.Handler {
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
start := time.Now()
|
|
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
|
|
next.ServeHTTP(ww, r)
|
|
c.reqs.WithLabelValues(http.StatusText(ww.Status()), r.Method, r.URL.Path).Inc()
|
|
c.latency.WithLabelValues(http.StatusText(ww.Status()), r.Method, r.URL.Path).Observe(float64(time.Since(start).Nanoseconds()) / 1000000)
|
|
}
|
|
|
|
return http.HandlerFunc(fn)
|
|
}
|