package api import ( "bufio" "fmt" "net" "net/http" "time" ) // wrapWithMetrics wraps a handler with Prometheus metrics tracking func (s *Server) wrapWithMetrics(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if s.promMetrics == nil { next.ServeHTTP(w, r) return } start := time.Now() // Track HTTP request method := r.Method endpoint := r.URL.Path // Wrap response writer to capture status code ww := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK} // Serve request next.ServeHTTP(ww, r) // Record metrics duration := time.Since(start) statusStr := http.StatusText(ww.statusCode) s.promMetrics.IncHTTPRequests(method, endpoint, statusStr) s.promMetrics.ObserveHTTPDuration(method, endpoint, duration) }) } // responseWriter wraps http.ResponseWriter to capture status code type responseWriter struct { http.ResponseWriter statusCode int } func (rw *responseWriter) WriteHeader(code int) { rw.statusCode = code rw.ResponseWriter.WriteHeader(code) } func (rw *responseWriter) Flush() { if f, ok := rw.ResponseWriter.(http.Flusher); ok { f.Flush() } } func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { h, ok := rw.ResponseWriter.(http.Hijacker) if !ok { return nil, nil, fmt.Errorf("websocket: response does not implement http.Hijacker") } return h.Hijack() }