fedimint_metrics/
server.rs

1//! HTTP server for exposing Prometheus metrics.
2//!
3//! This module is conditionally compiled only for non-wasm targets because it
4//! depends on `axum` and `tokio` networking features which are not available
5//! in wasm environments. The core metrics functionality (registration,
6//! encoding) remains available on all platforms via the parent module.
7
8use std::net::SocketAddr;
9
10use axum::Router;
11use axum::http::StatusCode;
12use axum::routing::get;
13use fedimint_core::task::TaskGroup;
14use tokio::net::TcpListener;
15use tracing::{info, warn};
16
17use super::get_metrics;
18
19async fn get_metrics_handler() -> (StatusCode, String) {
20    match get_metrics() {
21        Ok(result) => (StatusCode::OK, result),
22        Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")),
23    }
24}
25
26/// Spawns an HTTP server that exposes Prometheus metrics on `/metrics`.
27pub async fn spawn_api_server(
28    bind_address: SocketAddr,
29    task_group: TaskGroup,
30) -> anyhow::Result<()> {
31    let app = Router::new().route("/metrics", get(get_metrics_handler));
32    let listener = TcpListener::bind(bind_address).await?;
33
34    task_group.spawn_cancellable("Metrics Server", async move {
35        if let Err(e) = axum::serve(listener, app.into_make_service()).await {
36            warn!("Error running metrics server: {e:?}");
37        }
38    });
39
40    info!(
41        listen = %bind_address,
42        "Started metrics server"
43    );
44
45    Ok(())
46}