1use serde::{Deserialize, Serialize};
4use tracing::warn;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct AlertRule {
8 pub name: String,
9 pub metric: String,
10 pub threshold: f64,
11 pub comparison: Comparison,
12 pub action: AlertAction,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub enum Comparison {
17 GreaterThan,
18 LessThan,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub enum AlertAction {
23 Log,
24 Webhook { url: String },
25}
26
27pub struct AlertEngine {
28 rules: Vec<AlertRule>,
29}
30
31impl AlertEngine {
32 pub fn new(rules: Vec<AlertRule>) -> Self {
33 Self { rules }
34 }
35
36 pub fn evaluate(&self, metric_name: &str, value: f64) {
37 for rule in &self.rules {
38 if rule.metric != metric_name {
39 continue;
40 }
41 let triggered = match rule.comparison {
42 Comparison::GreaterThan => value > rule.threshold,
43 Comparison::LessThan => value < rule.threshold,
44 };
45 if triggered {
46 warn!(
47 alert = rule.name,
48 metric = metric_name,
49 value,
50 threshold = rule.threshold,
51 "alert triggered"
52 );
53 }
54 }
55 }
56}