pingql/apps/monitor/src/main.rs

65 lines
2.2 KiB
Rust

mod query;
mod runner;
mod types;
use anyhow::Result;
use std::collections::HashSet;
use std::env;
use std::sync::Arc;
use rustls;
use tokio::sync::Mutex;
use tokio::time::{sleep, Duration};
use tracing::{error, info};
#[tokio::main]
async fn main() -> Result<()> {
// Install default rustls crypto provider (required for cert expiry checks)
rustls::crypto::ring::default_provider()
.install_default()
.ok(); // ok() — ignore error if already installed
tracing_subscriber::fmt()
.with_env_filter(env::var("RUST_LOG").unwrap_or_else(|_| "info".into()))
.init();
let coordinator_url = env::var("COORDINATOR_URL")
.unwrap_or_else(|_| "http://localhost:3000".into());
let monitor_token = env::var("MONITOR_TOKEN")
.expect("MONITOR_TOKEN must be set");
let region = env::var("REGION").unwrap_or_default();
info!("PingQL monitor starting, coordinator: {coordinator_url}, region: {}", if region.is_empty() { "all" } else { &region });
let client = reqwest::Client::builder()
.user_agent("PingQL-Monitor/0.1")
.connect_timeout(std::time::Duration::from_secs(10))
.build()?;
let in_flight: Arc<Mutex<HashSet<String>>> = Arc::new(Mutex::new(HashSet::new()));
let shutdown = tokio::signal::ctrl_c();
tokio::pin!(shutdown);
loop {
tokio::select! {
_ = &mut shutdown => {
info!("Shutdown signal received, waiting for in-flight checks...");
let deadline = tokio::time::Instant::now() + Duration::from_secs(35);
while !in_flight.lock().await.is_empty() && tokio::time::Instant::now() < deadline {
sleep(Duration::from_millis(500)).await;
}
info!("Shutdown complete");
break;
}
_ = sleep(Duration::from_millis(500)) => {
match runner::fetch_and_run(&client, &coordinator_url, &monitor_token, &region, &in_flight).await {
Ok(n) => { if n > 0 { info!("Spawned {n} checks"); } },
Err(e) => error!("Check cycle failed: {e}"),
}
}
}
}
Ok(())
}