Instrumentation: Add histogram for request duration (#28364)

Signed-off-by: bergquist <carl.bergquist@gmail.com>
This commit is contained in:
Carl Bergquist 2020-10-20 09:44:38 +02:00 committed by GitHub
parent b036112444
commit edbaa9d681
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 23 deletions

View File

@ -7,12 +7,14 @@ import (
"time" "time"
"github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/setting"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
) )
var ( var (
httpRequestsInFlight prometheus.Gauge httpRequestsInFlight prometheus.Gauge
httpRequestDurationHistogram *prometheus.HistogramVec
) )
func init() { func init() {
@ -23,33 +25,52 @@ func init() {
}, },
) )
prometheus.MustRegister(httpRequestsInFlight) httpRequestDurationHistogram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: "grafana",
Name: "http_request_duration_seconds",
Help: "Histogram of latencies for HTTP requests.",
Buckets: []float64{.1, .2, .4, 1, 3, 8, 20, 60, 120},
},
[]string{"handler"},
)
prometheus.MustRegister(httpRequestsInFlight, httpRequestDurationHistogram)
} }
// RequestMetrics is a middleware handler that instruments the request // RequestMetrics is a middleware handler that instruments the request
func RequestMetrics(handler string) macaron.Handler { func RequestMetrics(cfg *setting.Cfg) func(handler string) macaron.Handler {
return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) { return func(handler string) macaron.Handler {
rw := res.(macaron.ResponseWriter) return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) {
now := time.Now() rw := res.(macaron.ResponseWriter)
httpRequestsInFlight.Inc() now := time.Now()
defer httpRequestsInFlight.Dec() httpRequestsInFlight.Inc()
c.Next() defer httpRequestsInFlight.Dec()
c.Next()
status := rw.Status() status := rw.Status()
code := sanitizeCode(status) code := sanitizeCode(status)
method := sanitizeMethod(req.Method) method := sanitizeMethod(req.Method)
metrics.MHttpRequestTotal.WithLabelValues(handler, code, method).Inc() metrics.MHttpRequestTotal.WithLabelValues(handler, code, method).Inc()
duration := time.Since(now).Nanoseconds() / int64(time.Millisecond)
metrics.MHttpRequestSummary.WithLabelValues(handler, code, method).Observe(float64(duration))
switch { duration := time.Since(now).Nanoseconds() / int64(time.Millisecond)
case strings.HasPrefix(req.RequestURI, "/api/datasources/proxy"):
countProxyRequests(status) // enable histogram and disable summaries for http requests.
case strings.HasPrefix(req.RequestURI, "/api/"): if cfg.IsHTTPRequestHistogramEnabled() {
countApiRequests(status) httpRequestDurationHistogram.WithLabelValues(handler).Observe(float64(duration))
default: } else {
countPageRequests(status) metrics.MHttpRequestSummary.WithLabelValues(handler, code, method).Observe(float64(duration))
}
switch {
case strings.HasPrefix(req.RequestURI, "/api/datasources/proxy"):
countProxyRequests(status)
case strings.HasPrefix(req.RequestURI, "/api/"):
countApiRequests(status)
default:
countPageRequests(status)
}
} }
} }
} }

View File

@ -273,7 +273,7 @@ func (s *Server) buildServiceGraph(services []*registry.Descriptor) error {
objs := []interface{}{ objs := []interface{}{
bus.GetBus(), bus.GetBus(),
s.cfg, s.cfg,
routing.NewRouteRegister(middleware.RequestMetrics, middleware.RequestTracing), routing.NewRouteRegister(middleware.RequestMetrics(s.cfg), middleware.RequestTracing),
localcache.New(5*time.Minute, 10*time.Minute), localcache.New(5*time.Minute, 10*time.Minute),
s, s,
} }

View File

@ -344,6 +344,10 @@ func (c Cfg) IsDatabaseMetricsEnabled() bool {
return c.FeatureToggles["database_metrics"] return c.FeatureToggles["database_metrics"]
} }
func (c Cfg) IsHTTPRequestHistogramEnabled() bool {
return c.FeatureToggles["http_request_histogram"]
}
type CommandLineArgs struct { type CommandLineArgs struct {
Config string Config string
HomePath string HomePath string