custom metrics with callback
genofire opened this issue · 4 comments
How to write custom metrics which query data out of a database?
e.g. count of users in database as a gauge
The answer depends when you want that metric to be updated. Would you like to update it on every call to an API route? In that case, you'd just add a piece of logic to your Rocket route to query the database and update your metric when the result is returned, using gauge.set(value)
. If you wanted to instead update that metric every 30 seconds, you'd need to spawn either a thread (if sync) or a task (if async) which queries the database, updates the gauge, then sleeps for 30 seconds and repeats.
both is useful if you ask me a async task would be nice ;)
Something like this should work:
use futures::StreamExt;
pub static USER_COUNT: once_cell::sync::Lazy<prometheus::IntGauge> =
once_cell::sync::Lazy::new(|| {
prometheus::IntGauge::new("user_count", "Number of users in database").unwrap()
});
async fn count_users() -> Result<i64, Box<dyn std::error::Error>> {
// // get database connection and run query
todo!()
}
async fn start_refreshing_user_count() {
tokio::time::interval(std::time::Duration::from_secs(30))
.for_each(|_| async {
match count_users().await {
Ok(val) => {
USER_COUNT.set(val);
}
Err(e) => {
tracing::warn!("Failed to update user count: {}", e);
}
};
})
.await;
}
#[tokio::main]
async fn main() {
tokio::spawn(start_refreshing_user_count());
// Do other stuff, like launching Rocket.
}
Is there a way to get it on call of /metrics
?