package middleware import ( "net/http" "strconv" "strings" "time" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus" ) var ( httpRequestsTotal = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total number of HTTP requests", }, []string{"method", "path", "status"}, ) httpRequestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "HTTP request duration in seconds", Buckets: prometheus.DefBuckets, }, []string{"method", "path", "status"}, ) ) func init() { prometheus.MustRegister(httpRequestsTotal) prometheus.MustRegister(httpRequestDuration) } func cleanPath(path string) string { segments := strings.Split(path, "/") for i, seg := range segments { if len(seg) == 26 { segments[i] = ":id" } } return strings.Join(segments, "/") } func MetricsMiddleware() gin.HandlerFunc { return func(c *gin.Context) { start := time.Now() path := cleanPath(c.Request.URL.Path) c.Next() status := strconv.Itoa(c.Writer.Status()) duration := time.Since(start).Seconds() httpRequestsTotal.WithLabelValues(c.Request.Method, path, status).Inc() httpRequestDuration.WithLabelValues(c.Request.Method, path, status).Observe(duration) if c.Writer.Status() == http.StatusNotFound && path == "/metrics" { return } } }