use std::{net::SocketAddr, str::FromStr}; use metrics::{Unit, counter, describe_counter, describe_gauge, gauge}; pub fn webhook_received(event_type: &str) { counter!("steep_webhooks_received_total", "event_type" => event_type.to_string()).increment(1); } pub fn webhook_duplicate(event_type: &str) { counter!("steep_webhooks_duplicate_total", "event_type" => event_type.to_string()).increment(1); } pub fn webhook_enqueue_failed(event_type: &str) { counter!("steep_webhooks_enqueue_failed_total", "event_type" => event_type.to_string()) .increment(1); } pub fn increment_task_active() { gauge!("steep_bot_tasks_active").increment(1.0); } pub fn decrement_task_active() { gauge!("steep_bot_tasks_active").decrement(1.0); } pub fn task_skipped(event_type: &str) { counter!("steep_bot_tasks_skipped_total", "event_type" => event_type.to_string()).increment(1); } pub fn task_completed(event_type: &str) { counter!("steep_bot_tasks_completed_total", "event_type" => event_type.to_string()) .increment(1); } pub fn task_failed(event_type: &str) { counter!("steep_bot_tasks_failed_total", "event_type" => event_type.to_string()).increment(1); } pub fn openrouter_cost_usd(cost: f64) { counter!("steep_openrouter_cost_cents_total").increment((cost * 100.0).round() as u64); } pub fn describe() { describe_counter!( "steep_webhooks_received_total", Unit::Count, "Total webhooks received" ); describe_counter!( "steep_webhooks_duplicate_total", Unit::Count, "Webhooks rejected as duplicates" ); describe_counter!( "steep_webhooks_enqueue_failed_total", Unit::Count, "Webhooks dropped because enqueueing to PostgreSQL failed" ); describe_gauge!( "steep_bot_tasks_active", Unit::Count, "Bot tasks currently in progress" ); describe_counter!( "steep_bot_tasks_skipped_total", Unit::Count, "Reviews skipped because they were already done" ); describe_counter!( "steep_bot_tasks_completed_total", Unit::Count, "Bot tasks completed successfully" ); describe_counter!( "steep_bot_tasks_failed_total", Unit::Count, "Bot tasks that failed" ); describe_counter!( "steep_openrouter_cost_cents_total", Unit::Count, "Total OpenRouter cost in cents (divide by 100 for USD)" ); } pub fn install(bind_addr: &str) -> anyhow::Result<()> { describe(); let builder = metrics_exporter_prometheus::PrometheusBuilder::new(); builder .with_http_listener(SocketAddr::from_str(bind_addr)?) .install()?; tracing::info!(bind_addr, "Prometheus metrics exporter installed"); Ok(()) }