LCOV - code coverage report
Current view: top level - proxy/src - metrics.rs (source / functions) Coverage Total Hit
Test: c639aa5f7ab62b43d647b10f40d15a15686ce8a9.info Lines: 96.1 % 231 222
Test Date: 2024-02-12 20:26:03 Functions: 94.4 % 54 51

            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 : });
        

Generated by: LCOV version 2.1-beta