77 lines
2.0 KiB
Rust
77 lines
2.0 KiB
Rust
use chrono::{DateTime, Utc};
|
|
use futures::lock::Mutex;
|
|
use log::info;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
|
|
pub type ServiceId = String;
|
|
|
|
#[derive(Debug)]
|
|
pub enum HealthStatus {
|
|
/// The service is up and running
|
|
Up,
|
|
|
|
/// The service gave an error when performing the health check
|
|
Errored,
|
|
|
|
/// The service did not respond to the health check
|
|
Down,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct ServiceConfig {
|
|
pub url: String,
|
|
pub mode: HttpHealthCheckMode,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub enum HttpHealthCheckMode {
|
|
/// Expect the server to return a 200 status code. The body is ignored.
|
|
Check200,
|
|
}
|
|
|
|
pub struct HealthState {
|
|
pub last_update: Mutex<Option<DateTime<Utc>>>,
|
|
pub health: HashMap<ServiceId, Mutex<Option<HealthStatus>>>,
|
|
pub config: HealthConfig,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct HealthConfig {
|
|
/// The time between updates (in seconds)
|
|
pub update_period: u64,
|
|
|
|
/// The list of services
|
|
pub services: HashMap<ServiceId, ServiceConfig>,
|
|
}
|
|
|
|
impl HealthState {
|
|
pub fn new(config: HealthConfig) -> HealthState {
|
|
HealthState {
|
|
last_update: Mutex::new(None),
|
|
health: config
|
|
.services
|
|
.iter()
|
|
.map(|(id, _config)| (id.clone(), Mutex::new(None)))
|
|
.collect(),
|
|
config,
|
|
}
|
|
}
|
|
|
|
pub async fn update(&self) {
|
|
*self.last_update.lock().await = Some(Utc::now());
|
|
|
|
for (id, status) in &self.health {
|
|
let url = &self.config.services[id].url;
|
|
info!("service [{}] querying {}", id, url);
|
|
let new_status = match reqwest::get(url).await {
|
|
Err(_) => HealthStatus::Down,
|
|
Ok(response) if response.status().is_success() => HealthStatus::Up,
|
|
Ok(_response) => HealthStatus::Errored,
|
|
};
|
|
info!("service [{}] new status {:?}", id, new_status);
|
|
*status.lock().await = Some(new_status);
|
|
}
|
|
}
|
|
}
|