aboutsummaryrefslogtreecommitdiff
path: root/src/log.rs
blob: 408df884cae8e86aa3da985273e94088466b32eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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(())
}