koprogo_api/infrastructure/web/handlers/
metrics.rs

1use actix_web::{get, http::header::AUTHORIZATION, HttpRequest, HttpResponse, Responder};
2use once_cell::sync::Lazy;
3use prometheus::{Encoder, TextEncoder};
4
5static METRICS_TOKEN: Lazy<Option<String>> = Lazy::new(|| std::env::var("METRICS_AUTH_TOKEN").ok());
6
7#[get("/metrics")]
8pub async fn metrics_endpoint(req: HttpRequest) -> impl Responder {
9    if let Some(expected) = METRICS_TOKEN.as_ref() {
10        let expected_header = format!("Bearer {}", expected);
11        let authorized = req
12            .headers()
13            .get(AUTHORIZATION)
14            .and_then(|h| h.to_str().ok())
15            .map(|header| header == expected_header)
16            .unwrap_or(false);
17
18        if !authorized {
19            return HttpResponse::Unauthorized().body("Unauthorized");
20        }
21    }
22
23    let encoder = TextEncoder::new();
24    let metric_families = prometheus::gather();
25
26    let mut buffer = Vec::new();
27    if let Err(err) = encoder.encode(&metric_families, &mut buffer) {
28        return HttpResponse::InternalServerError()
29            .body(format!("failed to encode metrics: {}", err));
30    }
31
32    HttpResponse::Ok()
33        .content_type(encoder.format_type())
34        .body(buffer)
35}