42 lines
1.1 KiB
Rust
42 lines
1.1 KiB
Rust
|
|
// Prometheus metrics endpoint
|
||
|
|
// Phase 5.2: Expose swarm and backend metrics
|
||
|
|
|
||
|
|
use axum::{
|
||
|
|
http::StatusCode,
|
||
|
|
response::{IntoResponse, Response},
|
||
|
|
};
|
||
|
|
use prometheus::{Encoder, TextEncoder};
|
||
|
|
|
||
|
|
/// Get Prometheus metrics in text format
|
||
|
|
pub async fn metrics_handler() -> Result<impl IntoResponse, MetricsError> {
|
||
|
|
let encoder = TextEncoder::new();
|
||
|
|
let metric_families = prometheus::gather();
|
||
|
|
|
||
|
|
let mut buffer = Vec::new();
|
||
|
|
encoder
|
||
|
|
.encode(&metric_families, &mut buffer)
|
||
|
|
.map_err(MetricsError::EncodingFailed)?;
|
||
|
|
|
||
|
|
Ok((
|
||
|
|
StatusCode::OK,
|
||
|
|
[("content-type", "text/plain; version=0.0.4; charset=utf-8")],
|
||
|
|
String::from_utf8_lossy(&buffer).to_string(),
|
||
|
|
))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Metrics endpoint errors
|
||
|
|
#[derive(Debug)]
|
||
|
|
pub enum MetricsError {
|
||
|
|
EncodingFailed(prometheus::Error),
|
||
|
|
}
|
||
|
|
|
||
|
|
impl IntoResponse for MetricsError {
|
||
|
|
fn into_response(self) -> Response {
|
||
|
|
let message = match self {
|
||
|
|
MetricsError::EncodingFailed(e) => format!("Failed to encode metrics: {:?}", e),
|
||
|
|
};
|
||
|
|
|
||
|
|
(StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
|
||
|
|
}
|
||
|
|
}
|