Add observabilitty and monitoring

This commit is contained in:
2026-03-03 06:39:42 +00:00
parent 2edb290563
commit b56c78fa07
15 changed files with 1549 additions and 38 deletions

View File

@@ -0,0 +1,62 @@
package observability
import (
"net/http"
"strconv"
"time"
"github.com/prometheus/client_golang/prometheus"
)
// MetricsMiddleware creates a middleware that records HTTP metrics.
func MetricsMiddleware(next http.Handler, registry *prometheus.Registry, _ interface{}) http.Handler {
if registry == nil {
// If metrics are not enabled, pass through without modification
return next
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// Record request size
if r.ContentLength > 0 {
httpRequestSize.WithLabelValues(r.Method, r.URL.Path).Observe(float64(r.ContentLength))
}
// Wrap response writer to capture status code and response size
wrapped := &metricsResponseWriter{
ResponseWriter: w,
statusCode: http.StatusOK,
bytesWritten: 0,
}
// Call the next handler
next.ServeHTTP(wrapped, r)
// Record metrics after request completes
duration := time.Since(start).Seconds()
status := strconv.Itoa(wrapped.statusCode)
httpRequestsTotal.WithLabelValues(r.Method, r.URL.Path, status).Inc()
httpRequestDuration.WithLabelValues(r.Method, r.URL.Path, status).Observe(duration)
httpResponseSize.WithLabelValues(r.Method, r.URL.Path).Observe(float64(wrapped.bytesWritten))
})
}
// metricsResponseWriter wraps http.ResponseWriter to capture status code and bytes written.
type metricsResponseWriter struct {
http.ResponseWriter
statusCode int
bytesWritten int
}
func (w *metricsResponseWriter) WriteHeader(statusCode int) {
w.statusCode = statusCode
w.ResponseWriter.WriteHeader(statusCode)
}
func (w *metricsResponseWriter) Write(b []byte) (int, error) {
n, err := w.ResponseWriter.Write(b)
w.bytesWritten += n
return n, err
}