Skip to main content

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`.
27///
28/// # Errors
29///
30/// Returns the error of binding `bind_address`.
31pub async fn spawn_api_server(
32    bind_address: SocketAddr,
33    task_group: TaskGroup,
34) -> std::io::Result<()> {
35    let app = Router::new().route("/metrics", get(get_metrics_handler));
36    let listener = TcpListener::bind(bind_address).await?;
37
38    task_group.spawn_cancellable("Metrics Server", async move {
39        if let Err(e) = axum::serve(listener, app.into_make_service()).await {
40            warn!("Error running metrics server: {e:?}");
41        }
42    });
43
44    info!(
45        listen = %bind_address,
46        "Started metrics server"
47    );
48
49    Ok(())
50}