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