use axum::{routing::get, Router}; use lazy_static::lazy_static; use log::warn; use prometheus::{IntCounterVec, Opts, Registry}; lazy_static! { pub static ref REGISTRY: Registry = Registry::new(); pub static ref REQUEST_COUNTER: IntCounterVec = IntCounterVec::new(Opts::new("requests", "Web requests"), &["method", "status", "route"]) .unwrap(); pub static ref REMINDER_COUNTER: IntCounterVec = IntCounterVec::new(Opts::new("reminders_sent", "Reminders sent"), &["channel"]).unwrap(); pub static ref REMINDER_FAIL_COUNTER: IntCounterVec = IntCounterVec::new( Opts::new("reminders_failed", "Reminders failed"), &["channel", "error"] ) .unwrap(); pub static ref COMMAND_COUNTER: IntCounterVec = IntCounterVec::new(Opts::new("commands", "Commands used"), &["command"]).unwrap(); } pub fn init_metrics() { REGISTRY.register(Box::new(REQUEST_COUNTER.clone())).unwrap(); REGISTRY.register(Box::new(REMINDER_COUNTER.clone())).unwrap(); REGISTRY.register(Box::new(REMINDER_FAIL_COUNTER.clone())).unwrap(); REGISTRY.register(Box::new(COMMAND_COUNTER.clone())).unwrap(); } pub async fn serve() { let app = Router::new().route("/metrics", get(metrics)); let listener = tokio::net::TcpListener::bind("localhost:31756").await.unwrap(); axum::serve(listener, app).await.unwrap(); } async fn metrics() -> String { let encoder = prometheus::TextEncoder::new(); let res_custom = encoder.encode_to_string(®ISTRY.gather()); res_custom.unwrap_or_else(|e| { warn!("Error encoding metrics: {:?}", e); String::new() }) }