github.com/thanos-io/thanos@v0.32.5/internal/cortex/querier/queryrange/instrumentation.go (about)

     1  // Copyright (c) The Cortex Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package queryrange
     5  
     6  import (
     7  	"context"
     8  	"time"
     9  
    10  	"github.com/prometheus/client_golang/prometheus"
    11  	"github.com/prometheus/client_golang/prometheus/promauto"
    12  	"github.com/weaveworks/common/instrument"
    13  )
    14  
    15  // InstrumentMiddleware can be inserted into the middleware chain to expose timing information.
    16  func InstrumentMiddleware(name string, metrics *InstrumentMiddlewareMetrics) Middleware {
    17  	var durationCol instrument.Collector
    18  
    19  	// Support the case metrics shouldn't be tracked (ie. unit tests).
    20  	if metrics != nil {
    21  		durationCol = instrument.NewHistogramCollector(metrics.duration)
    22  	} else {
    23  		durationCol = &NoopCollector{}
    24  	}
    25  
    26  	return MiddlewareFunc(func(next Handler) Handler {
    27  		return HandlerFunc(func(ctx context.Context, req Request) (Response, error) {
    28  			var resp Response
    29  			err := instrument.CollectedRequest(ctx, name, durationCol, instrument.ErrorCode, func(ctx context.Context) error {
    30  				var err error
    31  				resp, err = next.Do(ctx, req)
    32  				return err
    33  			})
    34  			return resp, err
    35  		})
    36  	})
    37  }
    38  
    39  // InstrumentMiddlewareMetrics holds the metrics tracked by InstrumentMiddleware.
    40  type InstrumentMiddlewareMetrics struct {
    41  	duration *prometheus.HistogramVec
    42  }
    43  
    44  // NewInstrumentMiddlewareMetrics makes a new InstrumentMiddlewareMetrics.
    45  func NewInstrumentMiddlewareMetrics(registerer prometheus.Registerer) *InstrumentMiddlewareMetrics {
    46  	return &InstrumentMiddlewareMetrics{
    47  		duration: promauto.With(registerer).NewHistogramVec(prometheus.HistogramOpts{
    48  			Namespace: "cortex",
    49  			Name:      "frontend_query_range_duration_seconds",
    50  			Help:      "Total time spent in seconds doing query range requests.",
    51  			Buckets:   prometheus.DefBuckets,
    52  		}, []string{"method", "status_code"}),
    53  	}
    54  }
    55  
    56  // NoopCollector is a noop collector that can be used as placeholder when no metric
    57  // should tracked by the instrumentation.
    58  type NoopCollector struct{}
    59  
    60  // Register implements instrument.Collector.
    61  func (c *NoopCollector) Register() {}
    62  
    63  // Before implements instrument.Collector.
    64  func (c *NoopCollector) Before(ctx context.Context, method string, start time.Time) {}
    65  
    66  // After implements instrument.Collector.
    67  func (c *NoopCollector) After(ctx context.Context, method, statusCode string, start time.Time) {}