github.com/thanos-io/thanos@v0.32.5/pkg/extprom/http/instrument_client.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package http
     5  
     6  import (
     7  	"net/http"
     8  
     9  	"github.com/prometheus/client_golang/prometheus"
    10  	"github.com/prometheus/client_golang/prometheus/promauto"
    11  	"github.com/prometheus/client_golang/prometheus/promhttp"
    12  )
    13  
    14  // ClientMetrics holds a collection of metrics that can be used to instrument a http client.
    15  // By setting this field in HTTPClientConfig, NewHTTPClient will create an instrumented client.
    16  type ClientMetrics struct {
    17  	inFlightGauge            prometheus.Gauge
    18  	requestTotalCount        *prometheus.CounterVec
    19  	dnsLatencyHistogram      *prometheus.HistogramVec
    20  	tlsLatencyHistogram      *prometheus.HistogramVec
    21  	requestDurationHistogram *prometheus.HistogramVec
    22  }
    23  
    24  // NewClientMetrics creates a new instance of ClientMetrics.
    25  // It will also register the metrics with the included register.
    26  // This ClientMetrics should be re-used for diff clients with the same purpose.
    27  // e.g. 1 ClientMetrics should be used for all the clients that talk to Alertmanager.
    28  func NewClientMetrics(reg prometheus.Registerer) *ClientMetrics {
    29  	var m ClientMetrics
    30  
    31  	m.inFlightGauge = promauto.With(reg).NewGauge(prometheus.GaugeOpts{
    32  		Subsystem: "http_client",
    33  		Name:      "in_flight_requests",
    34  		Help:      "A gauge of in-flight requests.",
    35  	})
    36  
    37  	m.requestTotalCount = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
    38  		Subsystem: "http_client",
    39  		Name:      "request_total",
    40  		Help:      "Total http client request by code and method.",
    41  	}, []string{"code", "method"})
    42  
    43  	m.dnsLatencyHistogram = promauto.With(reg).NewHistogramVec(
    44  		prometheus.HistogramOpts{
    45  			Subsystem: "http_client",
    46  			Name:      "dns_duration_seconds",
    47  			Help:      "Trace dns latency histogram.",
    48  			Buckets:   []float64{0.025, .05, .1, .5, 1, 5, 10},
    49  		},
    50  		[]string{"event"},
    51  	)
    52  
    53  	m.tlsLatencyHistogram = promauto.With(reg).NewHistogramVec(
    54  		prometheus.HistogramOpts{
    55  			Subsystem: "http_client",
    56  			Name:      "tls_duration_seconds",
    57  			Help:      "Trace tls latency histogram.",
    58  			Buckets:   []float64{0.025, .05, .1, .5, 1, 5, 10},
    59  		},
    60  		[]string{"event"},
    61  	)
    62  
    63  	m.requestDurationHistogram = promauto.With(reg).NewHistogramVec(
    64  		prometheus.HistogramOpts{
    65  			Subsystem: "http_client",
    66  			Name:      "request_duration_seconds",
    67  			Help:      "A histogram of request latencies.",
    68  			Buckets:   []float64{0.025, .05, .1, .5, 1, 5, 10},
    69  		},
    70  		[]string{"code", "method"},
    71  	)
    72  
    73  	return &m
    74  }
    75  
    76  // InstrumentedRoundTripper instruments the given roundtripper with metrics that are
    77  // registered in the provided ClientMetrics.
    78  func InstrumentedRoundTripper(tripper http.RoundTripper, m *ClientMetrics) http.RoundTripper {
    79  	if m == nil {
    80  		return tripper
    81  	}
    82  
    83  	trace := &promhttp.InstrumentTrace{
    84  		DNSStart: func(t float64) {
    85  			m.dnsLatencyHistogram.WithLabelValues("dns_start").Observe(t)
    86  		},
    87  		DNSDone: func(t float64) {
    88  			m.dnsLatencyHistogram.WithLabelValues("dns_done").Observe(t)
    89  		},
    90  		TLSHandshakeStart: func(t float64) {
    91  			m.tlsLatencyHistogram.WithLabelValues("tls_handshake_start").Observe(t)
    92  		},
    93  		TLSHandshakeDone: func(t float64) {
    94  			m.tlsLatencyHistogram.WithLabelValues("tls_handshake_done").Observe(t)
    95  		},
    96  	}
    97  
    98  	return promhttp.InstrumentRoundTripperInFlight(
    99  		m.inFlightGauge,
   100  		promhttp.InstrumentRoundTripperCounter(
   101  			m.requestTotalCount,
   102  			promhttp.InstrumentRoundTripperTrace(
   103  				trace,
   104  				promhttp.InstrumentRoundTripperDuration(
   105  					m.requestDurationHistogram,
   106  					tripper,
   107  				),
   108  			),
   109  		),
   110  	)
   111  }