asjeeves_telemetry/
database_metrics.rs1use std::fmt::Display;
2use std::sync::{Arc, OnceLock};
3use std::time::Instant;
4
5#[cfg(feature = "bb8")]
6use metrics::gauge;
7use metrics::histogram;
8
9static DB_CONFIG: OnceLock<DbConfig> = OnceLock::new();
10
11pub fn db_metrics_setup(name: impl Into<Arc<str>>, system: impl Into<Arc<str>>) {
12 let name: Arc<str> = name.into();
13 let system: Arc<str> = system.into();
14
15 let config = DbConfig { name, system };
16
17 let _ = DB_CONFIG.set(config);
18}
19
20pub async fn time_async_query<Closure, Fut, RetVal>(
21 query_name: impl Display,
22 query: Closure,
23) -> RetVal
24where
25 Closure: FnOnce() -> Fut,
26 Fut: Future<Output = RetVal>,
27{
28 let timer = Instant::now();
29
30 let result = query().await;
31
32 let system_name: &str = match DB_CONFIG.get() {
33 Some(config) => &config.system,
34 None => "",
35 };
36
37 let histogram = histogram!(
38 description: "Query execution time",
39 unit: metrics::Unit::Seconds,
40 "db.client.operation.duration",
41 "db.query.summary" => query_name.to_string(),
42 "db.system.name" => system_name
43 );
44
45 histogram.record(timer.elapsed().as_secs_f64());
46
47 result
48}
49
50#[cfg(feature = "bb8")]
51pub fn track_database_metrics(dbstate: bb8::State, pool_size: u32) {
52 let Some(config) = DB_CONFIG.get() else {
53 return;
54 };
55
56 let stats: bb8::Statistics = dbstate.statistics;
57
58 let active_connections: u32 = dbstate.connections - dbstate.idle_connections;
59
60 let pool_name: &str = &config.name;
61
62 let conn_count = gauge!(
63 description: "Active Connections",
64 unit: metrics::Unit::Count,
65 "db.client.connection.count",
66 "db.client.connetion.pool.name" => pool_name,
67 "db.client.connection.state" => "used",
68 );
69
70 let idle_count = gauge!(
71 description: "Idle Connections",
72 unit: metrics::Unit::Count,
73 "db.client.connection.count",
74 "db.client.connetion.pool.name" => pool_name,
75 "db.client.connection.state" => "idle",
76 );
77
78 let max_conn = gauge!(
79 description: "Pool Size",
80 unit: metrics::Unit::Count,
81 "db.client.connection.idle.max",
82 "db.client.connection.pool.name" => pool_name
83 );
84
85 let conn_get = gauge!(
86 description: "Connection aquisition duration",
87 unit: metrics::Unit::Seconds,
88 "db.client.connection.create_time",
89 "db.client.connection.pool.name" => pool_name
90 );
91
92 conn_count.set(active_connections as f64);
93 idle_count.set(dbstate.idle_connections as f64);
94 max_conn.set(pool_size as f64);
95 conn_get.set(stats.get_wait_time.as_secs_f64());
96}
97
98#[allow(dead_code)]
99struct DbConfig {
100 name: Arc<str>,
101 system: Arc<str>,
102}