diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0136f94 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,87 @@ +pub mod check; +pub mod web; +pub mod mail; + +use anyhow::{anyhow, Result}; +use axum::{routing::get, Router}; +use check::check_loop; +use log::error; +use serde::Deserialize; +use std::{ + collections::BTreeMap, + net::SocketAddr, + sync::Arc, + time::{Duration, SystemTime}, +}; +use tokio::{fs::read_to_string, sync::RwLock}; +use web::send_html_page; + +#[tokio::main] +async fn main() { + env_logger::init_from_env("LOG"); + if let Err(e) = run().await { + error!("{e:?}") + } +} + +#[derive(Debug, Deserialize)] +pub struct Config { + title: String, + bind: SocketAddr, + interval: u64, + services: Vec<Service>, +} + +#[derive(Debug, Deserialize)] +pub struct Service { + title: String, + checks: Vec<Check>, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum Check { + Systemd(String), + Http { title: Option<String>, url: String }, + Shell { title: String, command: String }, +} + +#[derive(Debug, Clone)] +pub struct Success { + pub latency: Option<Duration>, + pub updated: SystemTime, +} +impl Default for Success { + fn default() -> Self { + Self { + latency: None, + updated: SystemTime::now(), + } + } +} + +static STATUS: RwLock<BTreeMap<(usize, usize), Result<Success>>> = + RwLock::const_new(BTreeMap::new()); + +async fn run() -> anyhow::Result<()> { + let config = std::env::args() + .nth(1) + .ok_or(anyhow!("expected config path as first argument"))?; + let config = read_to_string(config).await?; + let config = Arc::<Config>::new(serde_yaml::from_str(&config)?); + + for i in 0..config.services.len() { + tokio::task::spawn(check_loop(config.clone(), i)); + } + + let app = Router::new().route( + "/", + get({ + let config = config.clone(); + move || send_html_page(config.clone()) + }), + ); + let listener = tokio::net::TcpListener::bind(config.bind).await?; + axum::serve(listener, app).await?; + Ok(()) +} |