Skip to main content

max / makenotwork

2.6 KB · 90 lines History Blame Raw
1 //! scan alert/recovery messages. Domain half of the Alerter split;
2 //! shared dispatch/cooldown plumbing lives in the parent module.
3
4 use tracing::instrument;
5
6 use super::{AlertCategory, AlertMeta, Alerter};
7
8 impl Alerter {
9 /// Fire when the scan pipeline transitions from operational → degraded or
10 /// unreachable. Includes the audit-doc threshold issues that fired.
11 #[instrument(skip_all)]
12 pub async fn send_scan_pipeline_alert(
13 &self,
14 target: &str,
15 label: &str,
16 status: &str,
17 issues: &[String],
18 ) {
19 let alert_key = format!("scan_pipeline:{target}");
20 let subject = format!("[PoM] {label}: scan pipeline {status}");
21 let body = format!(
22 "Target: {label} ({target})\n\
23 Status: {status}\n\
24 Issues:\n{}\n\
25 Instance: {}\n\
26 Time: {}\n\n\
27 Dashboard: <https://{}/admin/uploads>\n\n\
28 - PoM",
29 issues
30 .iter()
31 .map(|i| format!(" - {i}"))
32 .collect::<Vec<_>>()
33 .join("\n"),
34 self.instance_name,
35 chrono::Utc::now().to_rfc3339(),
36 target,
37 );
38
39 let priority = if status == "unreachable" {
40 "high"
41 } else {
42 "medium"
43 };
44 self.fire_failure(
45 &subject,
46 &body,
47 priority,
48 "pom-scan-pipeline",
49 Some(target),
50 AlertMeta {
51 key: &alert_key,
52 category: AlertCategory::ScanPipelineDegraded,
53 from: None,
54 to: Some(status),
55 error: None,
56 },
57 )
58 .await;
59 }
60
61 /// Fire on recovery from a degraded / unreachable scan-pipeline state.
62 #[instrument(skip_all)]
63 pub async fn send_scan_pipeline_recovery(&self, target: &str, label: &str) {
64 let alert_key = format!("scan_pipeline:{target}");
65 let subject = format!("[PoM] {label}: scan pipeline recovered");
66 let body = format!(
67 "Target: {label} ({target})\n\
68 Scan pipeline is operational.\n\
69 Instance: {}\n\
70 Time: {}\n\n\
71 - PoM",
72 self.instance_name,
73 chrono::Utc::now().to_rfc3339(),
74 );
75
76 self.fire_recovery(
77 &subject,
78 &body,
79 AlertMeta {
80 key: &alert_key,
81 category: AlertCategory::ScanPipelineRecovery,
82 from: None,
83 to: Some("operational"),
84 error: None,
85 },
86 )
87 .await;
88 }
89 }
90