feat: prometheus metrics

This commit is contained in:
trafficlunar 2025-06-30 15:22:28 +01:00
parent a2a99a8dcc
commit 28dd79f7c2
4 changed files with 94 additions and 1 deletions

View file

@ -0,0 +1,58 @@
package middleware
import (
"net/http"
"strconv"
"time"
"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: "Duration of HTTP requests",
Buckets: prometheus.DefBuckets,
},
[]string{"method", "path", "status"},
)
)
func init() {
prometheus.MustRegister(httpRequestsTotal, httpRequestDuration)
}
func PrometheusMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
rr := &responseRecorder{ResponseWriter: w, statusCode: 200}
next.ServeHTTP(rr, r)
duration := time.Since(start)
method := r.Method
path := r.URL.Path
status := strconv.Itoa(rr.statusCode)
httpRequestsTotal.WithLabelValues(method, path, status).Inc()
httpRequestDuration.WithLabelValues(method, path, status).Observe(duration.Seconds())
})
}
type responseRecorder struct {
http.ResponseWriter
statusCode int
}
func (rr *responseRecorder) WriteHeader(code int) {
rr.statusCode = code
rr.ResponseWriter.WriteHeader(code)
}

View file

@ -11,8 +11,10 @@ import (
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
"github.com/go-chi/httprate"
"github.com/prometheus/client_golang/prometheus/promhttp"
"api/internal/handler"
app_middleware "api/internal/middleware"
)
func getAllowedOrigins() []string {
@ -29,6 +31,7 @@ func NewRouter() {
r := chi.NewRouter()
// Middleware
r.Use(app_middleware.PrometheusMiddleware)
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(middleware.Logger)
@ -43,6 +46,9 @@ func NewRouter() {
MaxAge: 300,
}))
// Prometheus
r.Handle("/metrics", promhttp.Handler())
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{