aboutsummaryrefslogtreecommitdiff
path: root/src/log.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/log.rs')
-rw-r--r--src/log.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/log.rs b/src/log.rs
new file mode 100644
index 0000000..408df88
--- /dev/null
+++ b/src/log.rs
@@ -0,0 +1,53 @@
+use crate::{mail::send_mail, Config, STATUS};
+use chrono::{DateTime, Utc};
+use std::{
+ collections::{BTreeMap, VecDeque},
+ sync::Arc,
+};
+use tokio::sync::RwLock;
+
+static LAST_STATUS: RwLock<BTreeMap<usize, bool>> = RwLock::const_new(BTreeMap::new());
+pub static LOG: RwLock<VecDeque<Event>> = RwLock::const_new(VecDeque::new());
+
+pub struct Event {
+ pub time: DateTime<Utc>,
+ pub service: usize,
+ pub check: usize,
+ pub error: Option<String>,
+}
+
+pub async fn update_service(
+ config: Arc<Config>,
+ service: usize,
+ check: usize,
+ error: Option<(String, String)>,
+) -> anyhow::Result<()> {
+ let mut last_status = LAST_STATUS.write().await;
+ let last_status = last_status.entry(service).or_insert(true);
+ eprintln!("{service} {error:?}");
+
+ let current_status = {
+ let status = STATUS.read().await;
+ !status
+ .range((service, usize::MIN)..(service, usize::MAX))
+ .any(|(_, v)| v.is_err())
+ };
+
+ if *last_status != current_status {
+ *last_status = current_status;
+ let mut log = LOG.write().await;
+ log.push_front(Event {
+ error: error.clone().map(|(e, _)| e),
+ service,
+ check,
+ time: Utc::now(),
+ });
+ while log.len() > 32 {
+ log.pop_back();
+ }
+ if let Some((_short, long)) = error.clone() {
+ send_mail(&config, service, check, long).await?;
+ }
+ }
+ Ok(())
+}