Health and Metrics
Service Health
The /health
endpoint has nothing to check, because the reference implementation does not need to connect to any other services. Therefore, once the reference implementation is running, it can always report a healthy status:
async fn get_health() -> StatusCode {
StatusCode::OK
}
In practice, a connector should make sure that any upstream services can be successfully contacted, and respond accordingly.
Metrics
The reference implementation maintains some generic access metrics in its application state:
metrics.total_requests
counts the number of requests ever served, andmetrics.active_requests
counts the number of requests currently being served.
The metrics endpoint reports these metrics using the Rust prometheus crate:
async fn get_metrics(State(state): State<Arc<Mutex<AppState>>>) -> Result<String> {
let state = state.lock().await;
state.metrics.as_text().ok_or((
StatusCode::INTERNAL_SERVER_ERROR,
Json(models::ErrorResponse {
message: "cannot encode metrics".into(),
details: serde_json::Value::Null,
}),
))
}
To maintain these metrics, it uses a simple metrics middleware:
async fn metrics_middleware<T>(
state: State<Arc<Mutex<AppState>>>,
request: axum::http::Request<T>,
next: axum::middleware::Next<T>,
) -> axum::response::Response {
// Don't hold the lock to update metrics, since the
// lock doesn't protect the metrics anyway.
let metrics = {
let state = state.lock().await;
state.metrics.clone()
};
metrics.total_requests.inc();
metrics.active_requests.inc();
let response = next.run(request).await;
metrics.active_requests.dec();
response
}