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(())
}
|