use std::collections::HashMap; use axum::{extract::State, response::IntoResponse, Json}; use serde::{Deserialize, Serialize}; use crate::{service::ServiceHandles, Status}; pub mod services; pub fn router() -> axum::Router { use axum::routing::get; axum::Router::new() .route("/healthcheck", get(healthcheck)) .merge(services::router()) } #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct Health { #[serde(flatten)] pub status: Status, pub checks: HashMap, } impl From for Health { fn from(value: T) -> Self { Health { status: value.into(), ..Default::default() } } } impl IntoResponse for Health { fn into_response(self) -> axum::response::Response { Json(self).into_response() } } pub async fn healthcheck(State(services): State) -> Health { let checks = services .iter() .map(|(name, srv)| (name.clone(), srv.status())) .collect::>(); let status = match checks .values() .filter(|s| !matches!(s, Status::Pass)) .count() { 0 => Status::Pass, 1 => Status::Fail(Some("1 issue detected".to_string())), n => Status::Fail(Some(format!("{n} issues detected"))), }; Health { status, checks } }