mirror of
https://github.com/Warky-Devs/vecna.git
synced 2026-05-05 01:26:58 +00:00
63 lines
1.9 KiB
Go
63 lines
1.9 KiB
Go
package metrics
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/uptrace/bunrouter"
|
|
)
|
|
|
|
// Middleware returns a bunrouter middleware that records per-request Prometheus metrics.
|
|
// It reads timing from the RequestTrace stored in the context (set by server/trace.go).
|
|
// The trace target/url labels are optional; pass empty strings if not applicable.
|
|
func (r *Registry) Middleware(getTrace func(req bunrouter.Request) TraceSnapshot) bunrouter.MiddlewareFunc {
|
|
return func(next bunrouter.HandlerFunc) bunrouter.HandlerFunc {
|
|
return func(w http.ResponseWriter, req bunrouter.Request) error {
|
|
rw := &statusWriter{ResponseWriter: w, status: http.StatusOK}
|
|
err := next(rw, req)
|
|
|
|
snap := getTrace(req)
|
|
endpoint := req.URL.Path
|
|
status := fmt.Sprintf("%d", rw.status)
|
|
|
|
r.RequestsTotal.WithLabelValues(endpoint, status).Inc()
|
|
r.RequestDuration.WithLabelValues(endpoint).Observe(snap.TotalSeconds)
|
|
if snap.ForwardTarget != "" {
|
|
r.ForwardDuration.WithLabelValues(snap.ForwardTarget, snap.ForwardURL).Observe(snap.ForwardSeconds)
|
|
}
|
|
if snap.AdapterType != "" {
|
|
r.TranslateDuration.WithLabelValues(snap.AdapterType).Observe(snap.TranslateSeconds)
|
|
}
|
|
if snap.PromptTokens > 0 || snap.TotalTokens > 0 {
|
|
r.AddTokens(snap.ForwardTarget, snap.ForwardModel, snap.PromptTokens, snap.TotalTokens)
|
|
}
|
|
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
// TraceSnapshot carries the timing and usage values the metrics middleware needs.
|
|
type TraceSnapshot struct {
|
|
TotalSeconds float64
|
|
ForwardSeconds float64
|
|
TranslateSeconds float64
|
|
ForwardTarget string
|
|
ForwardURL string
|
|
ForwardModel string
|
|
AdapterType string
|
|
PromptTokens int
|
|
TotalTokens int
|
|
}
|
|
|
|
// statusWriter wraps http.ResponseWriter to capture the written status code.
|
|
type statusWriter struct {
|
|
http.ResponseWriter
|
|
status int
|
|
}
|
|
|
|
func (sw *statusWriter) WriteHeader(code int) {
|
|
sw.status = code
|
|
sw.ResponseWriter.WriteHeader(code)
|
|
}
|