use std::{
sync::{Arc, atomic::Ordering},
time::Instant,
};
use axum::{body::Body, extract::State, http::Request, middleware::Next, response::Response};
use crate::metrics_server::MetricsCollector;
pub async fn metrics_middleware(
State(metrics): State<Arc<MetricsCollector>>,
request: Request<Body>,
next: Next,
) -> Response {
metrics.http_requests_total.fetch_add(1, Ordering::Relaxed);
let start = Instant::now();
let response = next.run(request).await;
#[allow(clippy::cast_possible_truncation)]
let elapsed_us = start.elapsed().as_micros() as u64;
metrics.http_request_duration.observe_us(elapsed_us);
let status = response.status();
match status.as_u16() {
200..=299 => {
metrics.http_responses_2xx.fetch_add(1, Ordering::Relaxed);
},
400..=499 => {
metrics.http_responses_4xx.fetch_add(1, Ordering::Relaxed);
},
500..=599 => {
metrics.http_responses_5xx.fetch_add(1, Ordering::Relaxed);
},
_ => {
},
}
response
}