mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-01-10 04:18:14 +02:00
123 lines
4.2 KiB
Go
123 lines
4.2 KiB
Go
|
package middleware
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
|
||
|
"github.com/justinas/alice"
|
||
|
"github.com/prometheus/client_golang/prometheus"
|
||
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||
|
)
|
||
|
|
||
|
// DefaultMetricsHandler is the default http.Handler for serving metrics from
|
||
|
// the default prometheus.Registry
|
||
|
var DefaultMetricsHandler = NewMetricsHandlerWithDefaultRegistry()
|
||
|
|
||
|
// NewMetricsHandlerWithDefaultRegistry creates a new http.Handler for serving
|
||
|
// metrics from the default prometheus.Registry.
|
||
|
func NewMetricsHandlerWithDefaultRegistry() http.Handler {
|
||
|
return NewMetricsHandler(prometheus.DefaultRegisterer, prometheus.DefaultGatherer)
|
||
|
}
|
||
|
|
||
|
// NewMetricsHandler creates a new http.Handler for serving metrics from the
|
||
|
// provided prometheus.Registerer and prometheus.Gatherer
|
||
|
func NewMetricsHandler(registerer prometheus.Registerer, gatherer prometheus.Gatherer) http.Handler {
|
||
|
return promhttp.InstrumentMetricHandler(
|
||
|
registerer, promhttp.HandlerFor(gatherer, promhttp.HandlerOpts{}),
|
||
|
)
|
||
|
}
|
||
|
|
||
|
// NewRequestMetricsWithDefaultRegistry returns a middleware that will record
|
||
|
// metrics for HTTP requests to the default prometheus.Registry
|
||
|
func NewRequestMetricsWithDefaultRegistry() alice.Constructor {
|
||
|
return NewRequestMetrics(prometheus.DefaultRegisterer)
|
||
|
}
|
||
|
|
||
|
// NewRequestMetrics returns a middleware that will record metrics for HTTP
|
||
|
// requests to the provided prometheus.Registerer
|
||
|
func NewRequestMetrics(registerer prometheus.Registerer) alice.Constructor {
|
||
|
return func(next http.Handler) http.Handler {
|
||
|
// Counter for all requests
|
||
|
// This is bucketed based on the response code we set
|
||
|
counterHandler := func(next http.Handler) http.Handler {
|
||
|
return promhttp.InstrumentHandlerCounter(registerRequestsCounter(registerer), next)
|
||
|
}
|
||
|
|
||
|
// Gauge to all requests currently being handled
|
||
|
inFlightHandler := func(next http.Handler) http.Handler {
|
||
|
return promhttp.InstrumentHandlerInFlight(registerInflightRequestsGauge(registerer), next)
|
||
|
}
|
||
|
|
||
|
// The latency of all requests bucketed by HTTP method
|
||
|
durationHandler := func(next http.Handler) http.Handler {
|
||
|
return promhttp.InstrumentHandlerDuration(registerRequestsLatencyHistogram(registerer), next)
|
||
|
}
|
||
|
|
||
|
return alice.New(counterHandler, inFlightHandler, durationHandler).Then(next)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// registerRequestsCounter registers the 'oauth2_proxy_requests_total' metric
|
||
|
// This keeps a tally of all received requests bucket by their HTTP response
|
||
|
// status code
|
||
|
func registerRequestsCounter(registerer prometheus.Registerer) *prometheus.CounterVec {
|
||
|
counter := prometheus.NewCounterVec(
|
||
|
prometheus.CounterOpts{
|
||
|
Name: "oauth2_proxy_requests_total",
|
||
|
Help: "Total number of requests by HTTP status code.",
|
||
|
},
|
||
|
[]string{"code"},
|
||
|
)
|
||
|
|
||
|
if err := registerer.Register(counter); err != nil {
|
||
|
if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
|
||
|
counter = are.ExistingCollector.(*prometheus.CounterVec)
|
||
|
} else {
|
||
|
panic(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return counter
|
||
|
}
|
||
|
|
||
|
// registerInflightRequestsGauge registers 'oauth2_proxy_requests_in_flight'
|
||
|
// This only keeps the count of currently in progress HTTP requests
|
||
|
func registerInflightRequestsGauge(registerer prometheus.Registerer) prometheus.Gauge {
|
||
|
gauge := prometheus.NewGauge(prometheus.GaugeOpts{
|
||
|
Name: "oauth2_proxy_requests_in_flight",
|
||
|
Help: "Current number of requests being served.",
|
||
|
})
|
||
|
|
||
|
if err := registerer.Register(gauge); err != nil {
|
||
|
if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
|
||
|
gauge = are.ExistingCollector.(prometheus.Gauge)
|
||
|
} else {
|
||
|
panic(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return gauge
|
||
|
}
|
||
|
|
||
|
// registerRequestsLatencyHistogram registers 'oauth2_proxy_response_duration_seconds'
|
||
|
// This keeps tally of the requests bucketed by the time taken to process the request
|
||
|
func registerRequestsLatencyHistogram(registerer prometheus.Registerer) *prometheus.HistogramVec {
|
||
|
histogram := prometheus.NewHistogramVec(
|
||
|
prometheus.HistogramOpts{
|
||
|
Name: "oauth2_proxy_response_duration_seconds",
|
||
|
Help: "A histogram of request latencies.",
|
||
|
Buckets: prometheus.DefBuckets,
|
||
|
},
|
||
|
[]string{"method"},
|
||
|
)
|
||
|
|
||
|
if err := registerer.Register(histogram); err != nil {
|
||
|
if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
|
||
|
histogram = are.ExistingCollector.(*prometheus.HistogramVec)
|
||
|
} else {
|
||
|
panic(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return histogram
|
||
|
}
|