1
1
/*
2
- Copyright 2018 The Kubernetes Authors.
2
+ Copyright 2025 The Kubernetes Authors.
3
3
4
4
Licensed under the Apache License, Version 2.0 (the "License");
5
5
you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@ package metrics
18
18
19
19
import (
20
20
"context"
21
+ "net/url"
22
+ "time"
21
23
22
24
"github.com/prometheus/client_golang/prometheus"
23
25
clientmetrics "k8s.io/client-go/tools/metrics"
@@ -28,7 +30,59 @@ import (
28
30
// from Kubernetes so that we match the core controllers.
29
31
30
32
var (
31
- // client metrics.
33
+ // client metrics from https://github.com/kubernetes/kubernetes/blob/v1.33.0/staging/src/k8s.io/component-base/metrics/prometheus/restclient/metrics.go
34
+ // except for rest_client_exec_plugin_* metrics which controllers wouldn't use
35
+
36
+ // requestLatency is a Prometheus Histogram metric type partitioned by
37
+ // "verb", and "host" labels. It is used for the rest client latency metrics.
38
+ requestLatency = prometheus .NewHistogramVec (
39
+ prometheus.HistogramOpts {
40
+ Name : "rest_client_request_duration_seconds" ,
41
+ Help : "Request latency in seconds. Broken down by verb, and host." ,
42
+ 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 },
43
+ },
44
+ []string {"verb" , "host" },
45
+ )
46
+
47
+ // resolverLatency is a Prometheus Histogram metric type partitioned by
48
+ // "host" labels. It is used for the rest client DNS resolver latency metrics.
49
+ resolverLatency = prometheus .NewHistogramVec (
50
+ prometheus.HistogramOpts {
51
+ Name : "rest_client_dns_resolution_duration_seconds" ,
52
+ Help : "DNS resolver latency in seconds. Broken down by host." ,
53
+ Buckets : []float64 {0.005 , 0.025 , 0.1 , 0.25 , 0.5 , 1.0 , 2.0 , 4.0 , 8.0 , 15.0 , 30.0 },
54
+ },
55
+ []string {"host" },
56
+ )
57
+
58
+ requestSize = prometheus .NewHistogramVec (
59
+ prometheus.HistogramOpts {
60
+ Name : "rest_client_request_size_bytes" ,
61
+ Help : "Request size in bytes. Broken down by verb and host." ,
62
+ // 64 bytes to 16MB
63
+ Buckets : []float64 {64 , 256 , 512 , 1024 , 4096 , 16384 , 65536 , 262144 , 1048576 , 4194304 , 16777216 },
64
+ },
65
+ []string {"verb" , "host" },
66
+ )
67
+
68
+ responseSize = prometheus .NewHistogramVec (
69
+ prometheus.HistogramOpts {
70
+ Name : "rest_client_response_size_bytes" ,
71
+ Help : "Response size in bytes. Broken down by verb and host." ,
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 = prometheus .NewHistogramVec (
79
+ prometheus.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
+ 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 },
83
+ },
84
+ []string {"verb" , "host" },
85
+ )
32
86
33
87
requestResult = prometheus .NewCounterVec (
34
88
prometheus.CounterOpts {
37
91
},
38
92
[]string {"code" , "method" , "host" },
39
93
)
94
+
95
+ requestRetry = prometheus .NewCounterVec (
96
+ prometheus.CounterOpts {
97
+ Name : "rest_client_request_retries_total" ,
98
+ Help : "Number of request retries, partitioned by status code, verb, and host." ,
99
+ },
100
+ []string {"code" , "verb" , "host" },
101
+ )
102
+
103
+ transportCacheEntries = prometheus .NewGauge (
104
+ prometheus.GaugeOpts {
105
+ Name : "rest_client_transport_cache_entries" ,
106
+ Help : "Number of transport entries in the internal cache." ,
107
+ },
108
+ )
109
+
110
+ transportCacheCalls = prometheus .NewCounterVec (
111
+ prometheus.CounterOpts {
112
+ Name : "rest_client_transport_create_calls_total" ,
113
+ Help : "Number of calls to get a new transport, partitioned by the result of the operation " +
114
+ "hit: obtained from the cache, miss: created and added to the cache, uncacheable: created and not cached" ,
115
+ },
116
+ []string {"result" },
117
+ )
40
118
)
41
119
42
120
func init () {
@@ -46,26 +124,101 @@ func init() {
46
124
// registerClientMetrics sets up the client latency metrics from client-go.
47
125
func registerClientMetrics () {
48
126
// register the metrics with our registry
49
- Registry .MustRegister (requestResult )
127
+ Registry .MustRegister (requestResult ,
128
+ requestLatency ,
129
+ resolverLatency ,
130
+ requestSize ,
131
+ responseSize ,
132
+ rateLimiterLatency ,
133
+ requestRetry ,
134
+ transportCacheEntries ,
135
+ transportCacheCalls ,
136
+ )
50
137
51
138
// register the metrics with client-go
52
139
clientmetrics .Register (clientmetrics.RegisterOpts {
53
- RequestResult : & resultAdapter {metric : requestResult },
140
+ RequestResult : & requestResultAdapter {metric : requestResult },
141
+ RequestLatency : & requestLatencyAdapter {metric : requestLatency },
142
+ ResolverLatency : & resolverLatencyAdapter {metric : resolverLatency },
143
+ RequestSize : & requestSizeAdapter {metric : requestSize },
144
+ ResponseSize : & responseSizeAdapter {metric : responseSize },
145
+ RateLimiterLatency : & rateLimiterLatencyAdapter {metric : rateLimiterLatency },
146
+ RequestRetry : & requestRetryAdapter {metric : requestRetry },
147
+ TransportCacheEntries : & transportCacheEntriesAdapter {metric : transportCacheEntries },
148
+ TransportCreateCalls : & transportCreateCallsAdapter {metric : transportCacheCalls },
54
149
})
55
150
}
56
151
57
- // this section contains adapters, implementations, and other sundry organic, artisanally
58
- // hand-crafted syntax trees required to convince client-go that it actually wants to let
59
- // someone use its metrics.
152
+ // Prometheus adapters for client-go metrics hooks.
153
+
154
+ type requestResultAdapter struct {
155
+ metric * prometheus.CounterVec
156
+ }
157
+
158
+ func (r * requestResultAdapter ) Increment (_ context.Context , code , method , host string ) {
159
+ r .metric .WithLabelValues (code , method , host ).Inc ()
160
+ }
161
+
162
+ type requestLatencyAdapter struct {
163
+ metric * prometheus.HistogramVec
164
+ }
165
+
166
+ func (l * requestLatencyAdapter ) Observe (_ context.Context , verb string , u url.URL , latency time.Duration ) {
167
+ l .metric .WithLabelValues (verb , u .Host ).Observe (latency .Seconds ())
168
+ }
169
+
170
+ type resolverLatencyAdapter struct {
171
+ metric * prometheus.HistogramVec
172
+ }
173
+
174
+ func (r * resolverLatencyAdapter ) Observe (_ context.Context , host string , latency time.Duration ) {
175
+ r .metric .WithLabelValues (host ).Observe (latency .Seconds ())
176
+ }
177
+
178
+ type requestSizeAdapter struct {
179
+ metric * prometheus.HistogramVec
180
+ }
181
+
182
+ func (s * requestSizeAdapter ) Observe (_ context.Context , verb string , host string , size float64 ) {
183
+ s .metric .WithLabelValues (verb , host ).Observe (size )
184
+ }
185
+
186
+ type responseSizeAdapter struct {
187
+ metric * prometheus.HistogramVec
188
+ }
189
+
190
+ func (s * responseSizeAdapter ) Observe (_ context.Context , verb string , host string , size float64 ) {
191
+ s .metric .WithLabelValues (verb , host ).Observe (size )
192
+ }
193
+
194
+ type rateLimiterLatencyAdapter struct {
195
+ metric * prometheus.HistogramVec
196
+ }
60
197
61
- // Client metrics adapters (method #1 for client-go metrics),
62
- // copied (more-or-less directly) from k8s.io/kubernetes setup code
63
- // (which isn't anywhere in an easily-importable place).
198
+ func ( l * rateLimiterLatencyAdapter ) Observe ( _ context. Context , verb string , u url. URL , latency time. Duration ) {
199
+ l . metric . WithLabelValues ( verb , u . Host ). Observe ( latency . Seconds ())
200
+ }
64
201
65
- type resultAdapter struct {
202
+ type requestRetryAdapter struct {
66
203
metric * prometheus.CounterVec
67
204
}
68
205
69
- func (r * resultAdapter ) Increment (_ context.Context , code , method , host string ) {
206
+ func (r * requestRetryAdapter ) IncrementRetry (_ context.Context , code string , method string , host string ) {
70
207
r .metric .WithLabelValues (code , method , host ).Inc ()
71
208
}
209
+
210
+ type transportCacheEntriesAdapter struct {
211
+ metric prometheus.Gauge
212
+ }
213
+
214
+ func (t * transportCacheEntriesAdapter ) Observe (value int ) {
215
+ t .metric .Set (float64 (value ))
216
+ }
217
+
218
+ type transportCreateCallsAdapter struct {
219
+ metric * prometheus.CounterVec
220
+ }
221
+
222
+ func (t * transportCreateCallsAdapter ) Increment (result string ) {
223
+ t .metric .WithLabelValues (result ).Inc ()
224
+ }
0 commit comments