Skip to main content

autopush_common/db/
reporter.rs

1use std::{sync::Arc, time::Duration};
2
3use actix_web::rt;
4use cadence::{Gauged, StatsdClient};
5use gethostname::gethostname;
6
7use super::client::DbClient;
8
9/// Emit db pool (deadpool) metrics periodically
10pub fn spawn_pool_periodic_reporter(
11    interval: Duration,
12    db: Box<dyn DbClient>,
13    metrics: Arc<StatsdClient>,
14) {
15    let hostname = gethostname().to_string_lossy().to_string();
16    rt::spawn(async move {
17        loop {
18            pool_periodic_reporter(&*db, &metrics, &hostname);
19            rt::time::sleep(interval).await;
20        }
21    });
22}
23
24fn pool_periodic_reporter(db: &dyn DbClient, metrics: &StatsdClient, _hostname: &str) {
25    // The deadpool gauges count logical RPC slots, not connections. Naming them
26    // "pool" invited reading them as a connection count, which they have not
27    // been since channels were split out of pool entries.
28    if let Some(status) = db.pool_status() {
29        metrics
30            .gauge_with_tags(
31                "database.ops.inflight",
32                (status.size - status.available) as u64,
33            )
34            //.with_tag("hostname", hostname)  // Do not include hostname due to cardinality
35            .send();
36        metrics
37            .gauge_with_tags("database.ops.available", status.available as u64)
38            .send();
39        metrics
40            .gauge_with_tags("database.ops.queued", status.waiting as u64)
41            .send();
42    }
43
44    // One channel owns at most one HTTP/2 connection, so this is the ceiling on
45    // sockets to Bigtable. Channels connect lazily, so a slot that has not yet
46    // served an RPC has no socket and the true count can lag this at startup.
47    if let Some(count) = db.configured_channel_count() {
48        metrics
49            .gauge_with_tags("database.channels", count as u64)
50            .send();
51    }
52}