//! Reporter central — orchestre le snapshot et le logging de toutes les métriques. use std::sync::Arc; use std::time::Duration; use crate::metrics::AppMetrics; /// Lance une tâche tokio unique qui reporte toutes les métriques à intervalle régulier. pub fn spawn_reporter(metrics: Arc, interval: Duration) { let metrics_http = Arc::clone(&metrics.http); let metrics_udp = Arc::clone(&metrics.udp); tokio::spawn(async move { let mut ticker = tokio::time::interval(interval); ticker.tick().await; let mut prev_http = metrics_http.snapshot(); let mut prev_udp = metrics_udp.snapshot(); loop { ticker.tick().await; let current_http = metrics_http.snapshot(); let current_udp = metrics_udp.snapshot(); let http_rates = current_http.rates_since(&prev_http); let udp_rates = current_udp.rates_since(&prev_udp); tracing::info!( // ── HTTP ── http_requests_total = current_http.requests_total, http_responses_2xx = current_http.responses_2xx, http_responses_4xx = current_http.responses_4xx, http_responses_5xx = current_http.responses_5xx, http_req_per_sec = format_args!("{:.2}", http_rates.requests_per_sec), http_avg_latency_ms = format_args!("{:.1}", http_rates.avg_latency_ms), // ── UDP ── udp_pkts_rx = current_udp.packets_received, udp_pkts_tx = current_udp.packets_sent, udp_pkts_dropped = current_udp.packets_dropped, udp_pkts_rx_s = format_args!("{:.1}", udp_rates.packets_received_per_sec), udp_pkts_tx_s = format_args!("{:.1}", udp_rates.packets_sent_per_sec), "App metrics" ); prev_http = current_http; prev_udp = current_udp; } }); }