diff --git a/servers/https.go b/servers/https.go index c0e474c..4d4a0c5 100644 --- a/servers/https.go +++ b/servers/https.go @@ -27,9 +27,12 @@ func NewHttpsServer(conf *conf.Conf, registry *prometheus.Registry) *http.Server favMiddleware := setupFaviconMiddleware(conf.Favicons, r) rateLimiter := setupRateLimiter(conf.RateLimit, favMiddleware) metricsMiddleware := metrics.New(registry, nil).WrapHandler("violet-https", rateLimiter) + metricsMeta := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + metricsMiddleware.ServeHTTP(rw, metrics.AddHostCtx(req)) + }) hsts := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { rw.Header().Set("Strict-Transport-Security", "max-age=63072000; includeSubDomains") - metricsMiddleware.ServeHTTP(rw, req) + metricsMeta.ServeHTTP(rw, req) }) return &http.Server{ diff --git a/servers/metrics/httpmiddleware.go b/servers/metrics/httpmiddleware.go index 2ffc0ff..fe26594 100644 --- a/servers/metrics/httpmiddleware.go +++ b/servers/metrics/httpmiddleware.go @@ -1,6 +1,7 @@ package metrics import ( + "context" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -46,7 +47,7 @@ func (m *middleware) WrapHandler(handlerName string, handler http.Handler) http. prometheus.CounterOpts{ Name: "http_requests_total", Help: "Tracks the number of HTTP requests.", - }, []string{"method", "code"}, + }, []string{"method", "code", "host"}, ) requestDuration := promauto.With(reg).NewHistogramVec( prometheus.HistogramOpts{ @@ -54,23 +55,28 @@ func (m *middleware) WrapHandler(handlerName string, handler http.Handler) http. Help: "Tracks the latencies for HTTP requests.", Buckets: m.buckets, }, - []string{"method", "code"}, + []string{"method", "code", "host"}, ) requestSize := promauto.With(reg).NewSummaryVec( prometheus.SummaryOpts{ Name: "http_request_size_bytes", Help: "Tracks the size of HTTP requests.", }, - []string{"method", "code"}, + []string{"method", "code", "host"}, ) responseSize := promauto.With(reg).NewSummaryVec( prometheus.SummaryOpts{ Name: "http_response_size_bytes", Help: "Tracks the size of HTTP responses.", }, - []string{"method", "code"}, + []string{"method", "code", "host"}, ) + hostCtxGetter := promhttp.WithLabelFromCtx("host", func(ctx context.Context) string { + s, _ := ctx.Value(hostCtxKey(0)).(string) + return s + }) + // Wraps the provided http.Handler to observe the request result with the provided metrics. base := promhttp.InstrumentHandlerCounter( requestsTotal, @@ -81,9 +87,13 @@ func (m *middleware) WrapHandler(handlerName string, handler http.Handler) http. promhttp.InstrumentHandlerResponseSize( responseSize, handler, + hostCtxGetter, ), + hostCtxGetter, ), + hostCtxGetter, ), + hostCtxGetter, ) return base.ServeHTTP @@ -100,3 +110,9 @@ func New(registry prometheus.Registerer, buckets []float64) Middleware { registry: registry, } } + +type hostCtxKey uint8 + +func AddHostCtx(req *http.Request) *http.Request { + return req.WithContext(context.WithValue(req.Context(), hostCtxKey(0), req.Host)) +}