chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
var (
|
||||
httpRequests = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: "voice_platform", Subsystem: "http", Name: "requests_total",
|
||||
Help: "Total HTTP requests by service, method, route and status.",
|
||||
}, []string{"service", "method", "route", "status"})
|
||||
httpDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Namespace: "voice_platform", Subsystem: "http", Name: "request_duration_seconds",
|
||||
Help: "HTTP request duration by service, method and route.",
|
||||
Buckets: []float64{0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5},
|
||||
}, []string{"service", "method", "route"})
|
||||
httpInflight = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: "voice_platform", Subsystem: "http", Name: "inflight_requests",
|
||||
Help: "Current in-flight HTTP requests by service.",
|
||||
}, []string{"service"})
|
||||
)
|
||||
|
||||
func MetricsHandler() http.Handler { return promhttp.Handler() }
|
||||
|
||||
func metricsMiddleware(serviceName string, next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||
startedAt := time.Now()
|
||||
httpInflight.WithLabelValues(serviceName).Inc()
|
||||
defer httpInflight.WithLabelValues(serviceName).Dec()
|
||||
recorder := &statusRecorder{ResponseWriter: writer, status: http.StatusOK}
|
||||
defer func() {
|
||||
route := request.Pattern
|
||||
if route == "" {
|
||||
route = "unmatched"
|
||||
}
|
||||
httpRequests.WithLabelValues(serviceName, request.Method, route, strconv.Itoa(recorder.status)).Inc()
|
||||
httpDuration.WithLabelValues(serviceName, request.Method, route).Observe(time.Since(startedAt).Seconds())
|
||||
}()
|
||||
next.ServeHTTP(recorder, request)
|
||||
})
|
||||
}
|
||||
|
||||
type statusRecorder struct {
|
||||
http.ResponseWriter
|
||||
status int
|
||||
bytes int
|
||||
}
|
||||
|
||||
func (r *statusRecorder) WriteHeader(status int) {
|
||||
r.status = status
|
||||
r.ResponseWriter.WriteHeader(status)
|
||||
}
|
||||
|
||||
func (r *statusRecorder) Write(body []byte) (int, error) {
|
||||
written, err := r.ResponseWriter.Write(body)
|
||||
r.bytes += written
|
||||
return written, err
|
||||
}
|
||||
|
||||
func (r *statusRecorder) Unwrap() http.ResponseWriter { return r.ResponseWriter }
|
||||
Reference in New Issue
Block a user