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