//! peer alert/recovery messages. Domain half of the Alerter split; //! shared dispatch/cooldown plumbing lives in the parent module. use tracing::instrument; use super::{AlertCategory, AlertMeta, Alerter}; impl Alerter { #[instrument(skip_all)] pub async fn send_peer_missing( &self, peer_name: &str, address: &str, consecutive_failures: u32, ) { let alert_key = format!("peer:{peer_name}"); let subject = format!("[PoM] peer {peer_name}: missing"); let body = format!( "Peer: {peer_name}\n\ Address: {address}\n\ Consecutive failures: {consecutive_failures}\n\ Instance: {}\n\ Time: {}\n\n\ - PoM", self.instance_name, chrono::Utc::now().to_rfc3339(), ); self.fire_failure( &subject, &body, "high", "pom-peer", Some(peer_name), AlertMeta { key: &alert_key, category: AlertCategory::PeerMissing, from: None, to: None, error: None, }, ) .await; } #[instrument(skip_all)] pub async fn send_peer_recovery(&self, peer_name: &str, address: &str) { let subject = format!("[PoM] peer {peer_name}: recovered"); let body = format!( "Peer: {peer_name}\n\ Address: {address}\n\ Instance: {}\n\ Time: {}\n\n\ - PoM", self.instance_name, chrono::Utc::now().to_rfc3339(), ); let alert_key = format!("peer:{peer_name}"); self.fire_recovery( &subject, &body, AlertMeta { key: &alert_key, category: AlertCategory::PeerRecovery, from: None, to: None, error: None, }, ) .await; } }