diff options
Diffstat (limited to 'src/http_health.rs')
| -rw-r--r-- | src/http_health.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/http_health.rs b/src/http_health.rs new file mode 100644 index 0000000..0cdfeb5 --- /dev/null +++ b/src/http_health.rs | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | use axum::extract::State; | ||
| 2 | use axum::response::Json; | ||
| 3 | use axum::routing::get; | ||
| 4 | use axum::Router; | ||
| 5 | use serde_json::{json, Value}; | ||
| 6 | use std::sync::Arc; | ||
| 7 | use std::time::Instant; | ||
| 8 | use tokio::sync::watch; | ||
| 9 | |||
| 10 | pub struct HealthState { | ||
| 11 | pub started_at: Instant, | ||
| 12 | pub cycle_count: watch::Receiver<u64>, | ||
| 13 | pub last_cycle_ok: watch::Receiver<bool>, | ||
| 14 | pub db_path: String, | ||
| 15 | } | ||
| 16 | |||
| 17 | pub async fn start_health_server(port: u16, state: Arc<HealthState>) -> anyhow::Result<()> { | ||
| 18 | let app = Router::new() | ||
| 19 | .route("/health", get(health_handler)) | ||
| 20 | .route("/api/mirror-health", get(health_handler)) | ||
| 21 | .with_state(state); | ||
| 22 | |||
| 23 | let listener = tokio::net::TcpListener::bind(format!("127.0.0.1:{}", port)).await?; | ||
| 24 | tracing::info!(port, "health server listening"); | ||
| 25 | axum::serve(listener, app).await?; | ||
| 26 | Ok(()) | ||
| 27 | } | ||
| 28 | |||
| 29 | async fn health_handler(State(state): State<Arc<HealthState>>) -> Json<Value> { | ||
| 30 | let uptime = state.started_at.elapsed(); | ||
| 31 | let cycle_count = *state.cycle_count.borrow(); | ||
| 32 | let last_ok = *state.last_cycle_ok.borrow(); | ||
| 33 | |||
| 34 | Json(json!({ | ||
| 35 | "status": if last_ok || cycle_count == 0 { "ok" } else { "degraded" }, | ||
| 36 | "uptime_secs": uptime.as_secs(), | ||
| 37 | "cycle_count": cycle_count, | ||
| 38 | "last_cycle_ok": last_ok, | ||
| 39 | })) | ||
| 40 | } | ||