...

Source file src/k8s.io/component-base/metrics/prometheus/restclient/metrics.go

Documentation: k8s.io/component-base/metrics/prometheus/restclient

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package restclient
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"math"
    23  	"net/url"
    24  	"time"
    25  
    26  	"k8s.io/client-go/tools/metrics"
    27  	k8smetrics "k8s.io/component-base/metrics"
    28  	"k8s.io/component-base/metrics/legacyregistry"
    29  )
    30  
    31  var (
    32  	// requestLatency is a Prometheus Histogram metric type partitioned by
    33  	// "verb", and "host" labels. It is used for the rest client latency metrics.
    34  	requestLatency = k8smetrics.NewHistogramVec(
    35  		&k8smetrics.HistogramOpts{
    36  			Name:           "rest_client_request_duration_seconds",
    37  			Help:           "Request latency in seconds. Broken down by verb, and host.",
    38  			StabilityLevel: k8smetrics.ALPHA,
    39  			Buckets:        []float64{0.005, 0.025, 0.1, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0, 15.0, 30.0, 60.0},
    40  		},
    41  		[]string{"verb", "host"},
    42  	)
    43  
    44  	// resolverLatency is a Prometheus Histogram metric type partitioned by
    45  	// "host" labels. It is used for the rest client DNS resolver latency metrics.
    46  	resolverLatency = k8smetrics.NewHistogramVec(
    47  		&k8smetrics.HistogramOpts{
    48  			Name:           "rest_client_dns_resolution_duration_seconds",
    49  			Help:           "DNS resolver latency in seconds. Broken down by host.",
    50  			StabilityLevel: k8smetrics.ALPHA,
    51  			Buckets:        []float64{0.005, 0.025, 0.1, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0, 15.0, 30.0},
    52  		},
    53  		[]string{"host"},
    54  	)
    55  
    56  	requestSize = k8smetrics.NewHistogramVec(
    57  		&k8smetrics.HistogramOpts{
    58  			Name:           "rest_client_request_size_bytes",
    59  			Help:           "Request size in bytes. Broken down by verb and host.",
    60  			StabilityLevel: k8smetrics.ALPHA,
    61  			// 64 bytes to 16MB
    62  			Buckets: []float64{64, 256, 512, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216},
    63  		},
    64  		[]string{"verb", "host"},
    65  	)
    66  
    67  	responseSize = k8smetrics.NewHistogramVec(
    68  		&k8smetrics.HistogramOpts{
    69  			Name:           "rest_client_response_size_bytes",
    70  			Help:           "Response size in bytes. Broken down by verb and host.",
    71  			StabilityLevel: k8smetrics.ALPHA,
    72  			// 64 bytes to 16MB
    73  			Buckets: []float64{64, 256, 512, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216},
    74  		},
    75  		[]string{"verb", "host"},
    76  	)
    77  
    78  	rateLimiterLatency = k8smetrics.NewHistogramVec(
    79  		&k8smetrics.HistogramOpts{
    80  			Name:           "rest_client_rate_limiter_duration_seconds",
    81  			Help:           "Client side rate limiter latency in seconds. Broken down by verb, and host.",
    82  			StabilityLevel: k8smetrics.ALPHA,
    83  			Buckets:        []float64{0.005, 0.025, 0.1, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0, 15.0, 30.0, 60.0},
    84  		},
    85  		[]string{"verb", "host"},
    86  	)
    87  
    88  	requestResult = k8smetrics.NewCounterVec(
    89  		&k8smetrics.CounterOpts{
    90  			Name:           "rest_client_requests_total",
    91  			StabilityLevel: k8smetrics.ALPHA,
    92  			Help:           "Number of HTTP requests, partitioned by status code, method, and host.",
    93  		},
    94  		[]string{"code", "method", "host"},
    95  	)
    96  
    97  	requestRetry = k8smetrics.NewCounterVec(
    98  		&k8smetrics.CounterOpts{
    99  			Name:           "rest_client_request_retries_total",
   100  			StabilityLevel: k8smetrics.ALPHA,
   101  			Help:           "Number of request retries, partitioned by status code, verb, and host.",
   102  		},
   103  		[]string{"code", "verb", "host"},
   104  	)
   105  
   106  	execPluginCertTTLAdapter = &expiryToTTLAdapter{}
   107  
   108  	execPluginCertTTL = k8smetrics.NewGaugeFunc(
   109  		&k8smetrics.GaugeOpts{
   110  			Name: "rest_client_exec_plugin_ttl_seconds",
   111  			Help: "Gauge of the shortest TTL (time-to-live) of the client " +
   112  				"certificate(s) managed by the auth exec plugin. The value " +
   113  				"is in seconds until certificate expiry (negative if " +
   114  				"already expired). If auth exec plugins are unused or manage no " +
   115  				"TLS certificates, the value will be +INF.",
   116  			StabilityLevel: k8smetrics.ALPHA,
   117  		},
   118  		func() float64 {
   119  			if execPluginCertTTLAdapter.e == nil {
   120  				return math.Inf(1)
   121  			}
   122  			return execPluginCertTTLAdapter.e.Sub(time.Now()).Seconds()
   123  		},
   124  	)
   125  
   126  	execPluginCertRotation = k8smetrics.NewHistogram(
   127  		&k8smetrics.HistogramOpts{
   128  			Name: "rest_client_exec_plugin_certificate_rotation_age",
   129  			Help: "Histogram of the number of seconds the last auth exec " +
   130  				"plugin client certificate lived before being rotated. " +
   131  				"If auth exec plugin client certificates are unused, " +
   132  				"histogram will contain no data.",
   133  			// There are three sets of ranges these buckets intend to capture:
   134  			//   - 10-60 minutes: captures a rotation cadence which is
   135  			//     happening too quickly.
   136  			//   - 4 hours - 1 month: captures an ideal rotation cadence.
   137  			//   - 3 months - 4 years: captures a rotation cadence which is
   138  			//     is probably too slow or much too slow.
   139  			StabilityLevel: k8smetrics.ALPHA,
   140  			Buckets: []float64{
   141  				600,       // 10 minutes
   142  				1800,      // 30 minutes
   143  				3600,      // 1  hour
   144  				14400,     // 4  hours
   145  				86400,     // 1  day
   146  				604800,    // 1  week
   147  				2592000,   // 1  month
   148  				7776000,   // 3  months
   149  				15552000,  // 6  months
   150  				31104000,  // 1  year
   151  				124416000, // 4  years
   152  			},
   153  		},
   154  	)
   155  
   156  	execPluginCalls = k8smetrics.NewCounterVec(
   157  		&k8smetrics.CounterOpts{
   158  			StabilityLevel: k8smetrics.ALPHA,
   159  			Name:           "rest_client_exec_plugin_call_total",
   160  			Help: "Number of calls to an exec plugin, partitioned by the type of " +
   161  				"event encountered (no_error, plugin_execution_error, plugin_not_found_error, " +
   162  				"client_internal_error) and an optional exit code. The exit code will " +
   163  				"be set to 0 if and only if the plugin call was successful.",
   164  		},
   165  		[]string{"code", "call_status"},
   166  	)
   167  
   168  	transportCacheEntries = k8smetrics.NewGauge(
   169  		&k8smetrics.GaugeOpts{
   170  			Name:           "rest_client_transport_cache_entries",
   171  			StabilityLevel: k8smetrics.ALPHA,
   172  			Help:           "Number of transport entries in the internal cache.",
   173  		},
   174  	)
   175  
   176  	transportCacheCalls = k8smetrics.NewCounterVec(
   177  		&k8smetrics.CounterOpts{
   178  			Name:           "rest_client_transport_create_calls_total",
   179  			StabilityLevel: k8smetrics.ALPHA,
   180  			Help: "Number of calls to get a new transport, partitioned by the result of the operation " +
   181  				"hit: obtained from the cache, miss: created and added to the cache, uncacheable: created and not cached",
   182  		},
   183  		[]string{"result"},
   184  	)
   185  )
   186  
   187  func init() {
   188  
   189  	legacyregistry.MustRegister(requestLatency)
   190  	legacyregistry.MustRegister(requestSize)
   191  	legacyregistry.MustRegister(responseSize)
   192  	legacyregistry.MustRegister(rateLimiterLatency)
   193  	legacyregistry.MustRegister(requestResult)
   194  	legacyregistry.MustRegister(requestRetry)
   195  	legacyregistry.RawMustRegister(execPluginCertTTL)
   196  	legacyregistry.MustRegister(execPluginCertRotation)
   197  	legacyregistry.MustRegister(execPluginCalls)
   198  	legacyregistry.MustRegister(transportCacheEntries)
   199  	legacyregistry.MustRegister(transportCacheCalls)
   200  	metrics.Register(metrics.RegisterOpts{
   201  		ClientCertExpiry:      execPluginCertTTLAdapter,
   202  		ClientCertRotationAge: &rotationAdapter{m: execPluginCertRotation},
   203  		RequestLatency:        &latencyAdapter{m: requestLatency},
   204  		ResolverLatency:       &resolverLatencyAdapter{m: resolverLatency},
   205  		RequestSize:           &sizeAdapter{m: requestSize},
   206  		ResponseSize:          &sizeAdapter{m: responseSize},
   207  		RateLimiterLatency:    &latencyAdapter{m: rateLimiterLatency},
   208  		RequestResult:         &resultAdapter{requestResult},
   209  		RequestRetry:          &retryAdapter{requestRetry},
   210  		ExecPluginCalls:       &callsAdapter{m: execPluginCalls},
   211  		TransportCacheEntries: &transportCacheAdapter{m: transportCacheEntries},
   212  		TransportCreateCalls:  &transportCacheCallsAdapter{m: transportCacheCalls},
   213  	})
   214  }
   215  
   216  type latencyAdapter struct {
   217  	m *k8smetrics.HistogramVec
   218  }
   219  
   220  func (l *latencyAdapter) Observe(ctx context.Context, verb string, u url.URL, latency time.Duration) {
   221  	l.m.WithContext(ctx).WithLabelValues(verb, u.Host).Observe(latency.Seconds())
   222  }
   223  
   224  type resolverLatencyAdapter struct {
   225  	m *k8smetrics.HistogramVec
   226  }
   227  
   228  func (l *resolverLatencyAdapter) Observe(ctx context.Context, host string, latency time.Duration) {
   229  	l.m.WithContext(ctx).WithLabelValues(host).Observe(latency.Seconds())
   230  }
   231  
   232  type sizeAdapter struct {
   233  	m *k8smetrics.HistogramVec
   234  }
   235  
   236  func (s *sizeAdapter) Observe(ctx context.Context, verb string, host string, size float64) {
   237  	s.m.WithContext(ctx).WithLabelValues(verb, host).Observe(size)
   238  }
   239  
   240  type resultAdapter struct {
   241  	m *k8smetrics.CounterVec
   242  }
   243  
   244  func (r *resultAdapter) Increment(ctx context.Context, code, method, host string) {
   245  	r.m.WithContext(ctx).WithLabelValues(code, method, host).Inc()
   246  }
   247  
   248  type expiryToTTLAdapter struct {
   249  	e *time.Time
   250  }
   251  
   252  func (e *expiryToTTLAdapter) Set(expiry *time.Time) {
   253  	e.e = expiry
   254  }
   255  
   256  type rotationAdapter struct {
   257  	m *k8smetrics.Histogram
   258  }
   259  
   260  func (r *rotationAdapter) Observe(d time.Duration) {
   261  	r.m.Observe(d.Seconds())
   262  }
   263  
   264  type callsAdapter struct {
   265  	m *k8smetrics.CounterVec
   266  }
   267  
   268  func (r *callsAdapter) Increment(code int, callStatus string) {
   269  	r.m.WithLabelValues(fmt.Sprintf("%d", code), callStatus).Inc()
   270  }
   271  
   272  type retryAdapter struct {
   273  	m *k8smetrics.CounterVec
   274  }
   275  
   276  func (r *retryAdapter) IncrementRetry(ctx context.Context, code, method, host string) {
   277  	r.m.WithContext(ctx).WithLabelValues(code, method, host).Inc()
   278  }
   279  
   280  type transportCacheAdapter struct {
   281  	m *k8smetrics.Gauge
   282  }
   283  
   284  func (t *transportCacheAdapter) Observe(value int) {
   285  	t.m.Set(float64(value))
   286  }
   287  
   288  type transportCacheCallsAdapter struct {
   289  	m *k8smetrics.CounterVec
   290  }
   291  
   292  func (t *transportCacheCallsAdapter) Increment(result string) {
   293  	t.m.WithLabelValues(result).Inc()
   294  }
   295  

View as plain text