Line data Source code
1 : use ::metrics::{
2 : exponential_buckets, register_histogram, register_histogram_vec, register_hll_vec,
3 : register_int_counter_pair_vec, register_int_counter_vec, register_int_gauge,
4 : register_int_gauge_vec, Histogram, HistogramVec, HyperLogLogVec, IntCounterPairVec,
5 : IntCounterVec, IntGauge, IntGaugeVec,
6 : };
7 : use metrics::{register_int_counter_pair, IntCounterPair};
8 :
9 : use once_cell::sync::Lazy;
10 : use tokio::time;
11 :
12 23 : pub static NUM_DB_CONNECTIONS_GAUGE: Lazy<IntCounterPairVec> = Lazy::new(|| {
13 46 : register_int_counter_pair_vec!(
14 46 : "proxy_opened_db_connections_total",
15 46 : "Number of opened connections to a database.",
16 46 : "proxy_closed_db_connections_total",
17 46 : "Number of closed connections to a database.",
18 46 : &["protocol"],
19 46 : )
20 23 : .unwrap()
21 23 : });
22 :
23 24 : pub static NUM_CLIENT_CONNECTION_GAUGE: Lazy<IntCounterPairVec> = Lazy::new(|| {
24 48 : register_int_counter_pair_vec!(
25 48 : "proxy_opened_client_connections_total",
26 48 : "Number of opened connections from a client.",
27 48 : "proxy_closed_client_connections_total",
28 48 : "Number of closed connections from a client.",
29 48 : &["protocol"],
30 48 : )
31 24 : .unwrap()
32 24 : });
33 :
34 24 : pub static NUM_CONNECTION_REQUESTS_GAUGE: Lazy<IntCounterPairVec> = Lazy::new(|| {
35 48 : register_int_counter_pair_vec!(
36 48 : "proxy_accepted_connections_total",
37 48 : "Number of client connections accepted.",
38 48 : "proxy_closed_connections_total",
39 48 : "Number of client connections closed.",
40 48 : &["protocol"],
41 48 : )
42 24 : .unwrap()
43 24 : });
44 :
45 87 : pub static COMPUTE_CONNECTION_LATENCY: Lazy<HistogramVec> = Lazy::new(|| {
46 87 : register_histogram_vec!(
47 87 : "proxy_compute_connection_latency_seconds",
48 87 : "Time it took for proxy to establish a connection to the compute endpoint",
49 87 : // http/ws/tcp, true/false, true/false, success/failure
50 87 : // 3 * 2 * 2 * 2 = 24 counters
51 87 : &["protocol", "cache_miss", "pool_miss", "outcome"],
52 87 : // largest bucket = 2^16 * 0.5ms = 32s
53 87 : exponential_buckets(0.0005, 2.0, 16).unwrap(),
54 87 : )
55 87 : .unwrap()
56 87 : });
57 :
58 1 : pub static CONSOLE_REQUEST_LATENCY: Lazy<HistogramVec> = Lazy::new(|| {
59 1 : register_histogram_vec!(
60 1 : "proxy_console_request_latency",
61 1 : "Time it took for proxy to establish a connection to the compute endpoint",
62 1 : // proxy_wake_compute/proxy_get_role_info
63 1 : &["request"],
64 1 : // largest bucket = 2^16 * 0.2ms = 13s
65 1 : exponential_buckets(0.0002, 2.0, 16).unwrap(),
66 1 : )
67 1 : .unwrap()
68 1 : });
69 :
70 1 : pub static ALLOWED_IPS_BY_CACHE_OUTCOME: Lazy<IntCounterVec> = Lazy::new(|| {
71 1 : register_int_counter_vec!(
72 1 : "proxy_allowed_ips_cache_misses",
73 1 : "Number of cache hits/misses for allowed ips",
74 1 : // hit/miss
75 1 : &["outcome"],
76 1 : )
77 1 : .unwrap()
78 1 : });
79 :
80 3 : pub static RATE_LIMITER_ACQUIRE_LATENCY: Lazy<Histogram> = Lazy::new(|| {
81 3 : register_histogram!(
82 3 : "proxy_control_plane_token_acquire_seconds",
83 3 : "Time it took for proxy to establish a connection to the compute endpoint",
84 3 : // largest bucket = 3^16 * 0.05ms = 2.15s
85 3 : exponential_buckets(0.00005, 3.0, 16).unwrap(),
86 3 : )
87 3 : .unwrap()
88 3 : });
89 :
90 17 : pub static RATE_LIMITER_LIMIT: Lazy<IntGaugeVec> = Lazy::new(|| {
91 17 : register_int_gauge_vec!(
92 17 : "semaphore_control_plane_limit",
93 17 : "Current limit of the semaphore control plane",
94 17 : &["limit"], // 2 counters
95 17 : )
96 17 : .unwrap()
97 17 : });
98 :
99 42 : pub static NUM_CONNECTION_ACCEPTED_BY_SNI: Lazy<IntCounterVec> = Lazy::new(|| {
100 42 : register_int_counter_vec!(
101 42 : "proxy_accepted_connections_by_sni",
102 42 : "Number of connections (per sni).",
103 42 : &["kind"],
104 42 : )
105 42 : .unwrap()
106 42 : });
107 :
108 0 : pub static ALLOWED_IPS_NUMBER: Lazy<Histogram> = Lazy::new(|| {
109 0 : register_histogram!(
110 0 : "proxy_allowed_ips_number",
111 0 : "Number of allowed ips",
112 0 : vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 20.0, 50.0, 100.0],
113 0 : )
114 0 : .unwrap()
115 0 : });
116 :
117 13 : pub static HTTP_CONTENT_LENGTH: Lazy<Histogram> = Lazy::new(|| {
118 13 : register_histogram!(
119 13 : "proxy_http_conn_content_length_bytes",
120 13 : "Time it took for proxy to establish a connection to the compute endpoint",
121 13 : // largest bucket = 3^16 * 0.05ms = 2.15s
122 13 : exponential_buckets(8.0, 2.0, 20).unwrap()
123 13 : )
124 13 : .unwrap()
125 13 : });
126 :
127 27 : pub static GC_LATENCY: Lazy<Histogram> = Lazy::new(|| {
128 27 : register_histogram!(
129 27 : "proxy_http_pool_reclaimation_lag_seconds",
130 27 : "Time it takes to reclaim unused connection pools",
131 27 : // 1us -> 65ms
132 27 : exponential_buckets(1e-6, 2.0, 16).unwrap(),
133 27 : )
134 27 : .unwrap()
135 27 : });
136 :
137 15 : pub static ENDPOINT_POOLS: Lazy<IntCounterPair> = Lazy::new(|| {
138 30 : register_int_counter_pair!(
139 30 : "proxy_http_pool_endpoints_registered_total",
140 30 : "Number of endpoints we have registered pools for",
141 30 : "proxy_http_pool_endpoints_unregistered_total",
142 30 : "Number of endpoints we have unregistered pools for",
143 30 : )
144 15 : .unwrap()
145 15 : });
146 :
147 14 : pub static NUM_OPEN_CLIENTS_IN_HTTP_POOL: Lazy<IntGauge> = Lazy::new(|| {
148 14 : register_int_gauge!(
149 14 : "proxy_http_pool_opened_connections",
150 14 : "Number of opened connections to a database.",
151 14 : )
152 14 : .unwrap()
153 14 : });
154 :
155 0 : #[derive(Clone)]
156 : pub struct LatencyTimer {
157 : // time since the stopwatch was started
158 : start: Option<time::Instant>,
159 : // accumulated time on the stopwatch
160 : pub accumulated: std::time::Duration,
161 : // label data
162 : protocol: &'static str,
163 : cache_miss: bool,
164 : pool_miss: bool,
165 : outcome: &'static str,
166 : }
167 :
168 : pub struct LatencyTimerPause<'a> {
169 : timer: &'a mut LatencyTimer,
170 : }
171 :
172 : impl LatencyTimer {
173 176 : pub fn new(protocol: &'static str) -> Self {
174 176 : Self {
175 176 : start: Some(time::Instant::now()),
176 176 : accumulated: std::time::Duration::ZERO,
177 176 : protocol,
178 176 : cache_miss: false,
179 176 : // by default we don't do pooling
180 176 : pool_miss: true,
181 176 : // assume failed unless otherwise specified
182 176 : outcome: "failed",
183 176 : }
184 176 : }
185 :
186 129 : pub fn pause(&mut self) -> LatencyTimerPause<'_> {
187 129 : // stop the stopwatch and record the time that we have accumulated
188 129 : let start = self.start.take().expect("latency timer should be started");
189 129 : self.accumulated += start.elapsed();
190 129 : LatencyTimerPause { timer: self }
191 129 : }
192 :
193 12 : pub fn cache_miss(&mut self) {
194 12 : self.cache_miss = true;
195 12 : }
196 :
197 4 : pub fn pool_hit(&mut self) {
198 4 : self.pool_miss = false;
199 4 : }
200 :
201 137 : pub fn success(&mut self) {
202 : // stop the stopwatch and record the time that we have accumulated
203 137 : if let Some(start) = self.start.take() {
204 93 : self.accumulated += start.elapsed();
205 93 : }
206 :
207 : // success
208 137 : self.outcome = "success";
209 137 : }
210 : }
211 :
212 : impl Drop for LatencyTimerPause<'_> {
213 129 : fn drop(&mut self) {
214 129 : // start the stopwatch again
215 129 : self.timer.start = Some(time::Instant::now());
216 129 : }
217 : }
218 :
219 : impl Drop for LatencyTimer {
220 176 : fn drop(&mut self) {
221 176 : let duration =
222 176 : self.start.map(|start| start.elapsed()).unwrap_or_default() + self.accumulated;
223 176 : COMPUTE_CONNECTION_LATENCY
224 176 : .with_label_values(&[
225 176 : self.protocol,
226 176 : bool_to_str(self.cache_miss),
227 176 : bool_to_str(self.pool_miss),
228 176 : self.outcome,
229 176 : ])
230 176 : .observe(duration.as_secs_f64())
231 176 : }
232 : }
233 :
234 12 : pub static NUM_CONNECTION_FAILURES: Lazy<IntCounterVec> = Lazy::new(|| {
235 12 : register_int_counter_vec!(
236 12 : "proxy_connection_failures_total",
237 12 : "Number of connection failures (per kind).",
238 12 : &["kind"],
239 12 : )
240 12 : .unwrap()
241 12 : });
242 :
243 4 : pub static NUM_WAKEUP_FAILURES: Lazy<IntCounterVec> = Lazy::new(|| {
244 4 : register_int_counter_vec!(
245 4 : "proxy_connection_failures_breakdown",
246 4 : "Number of wake-up failures (per kind).",
247 4 : &["retry", "kind"],
248 4 : )
249 4 : .unwrap()
250 4 : });
251 :
252 24 : pub static NUM_BYTES_PROXIED_COUNTER: Lazy<IntCounterVec> = Lazy::new(|| {
253 24 : register_int_counter_vec!(
254 24 : "proxy_io_bytes",
255 24 : "Number of bytes sent/received between all clients and backends.",
256 24 : &["direction"],
257 24 : )
258 24 : .unwrap()
259 24 : });
260 :
261 356 : pub const fn bool_to_str(x: bool) -> &'static str {
262 356 : if x {
263 186 : "true"
264 : } else {
265 170 : "false"
266 : }
267 356 : }
268 :
269 34 : pub static CONNECTING_ENDPOINTS: Lazy<HyperLogLogVec<32>> = Lazy::new(|| {
270 34 : register_hll_vec!(
271 34 : 32,
272 34 : "proxy_connecting_endpoints",
273 34 : "HLL approximate cardinality of endpoints that are connecting",
274 34 : &["protocol"],
275 34 : )
276 34 : .unwrap()
277 34 : });
278 :
279 4 : pub static ERROR_BY_KIND: Lazy<IntCounterVec> = Lazy::new(|| {
280 4 : register_int_counter_vec!(
281 4 : "proxy_errors_total",
282 4 : "Number of errors by a given classification",
283 4 : &["type"],
284 4 : )
285 4 : .unwrap()
286 4 : });
287 :
288 3 : pub static ENDPOINT_ERRORS_BY_KIND: Lazy<HyperLogLogVec<32>> = Lazy::new(|| {
289 3 : register_hll_vec!(
290 3 : 32,
291 3 : "proxy_endpoints_affected_by_errors",
292 3 : "Number of endpoints affected by errors of a given classification",
293 3 : &["type"],
294 3 : )
295 3 : .unwrap()
296 3 : });
|