spawn_access_control/
alert_system.rs

1use crate::monitoring::{self, HealthAlert};
2use chrono::{DateTime, Utc};
3use serde::{Serialize, Deserialize};
4use tokio::sync::broadcast;
5use std::collections::HashMap;
6use async_trait::async_trait;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub enum AlertSeverity {
10    Critical,
11    Warning,
12    Info,
13}
14
15impl std::fmt::Display for AlertSeverity {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        match self {
18            Self::Critical => write!(f, "CRITICAL"),
19            Self::Warning => write!(f, "WARNING"),
20            Self::Info => write!(f, "INFO"),
21        }
22    }
23}
24
25impl From<&monitoring::AlertSeverity> for AlertSeverity {
26    fn from(severity: &monitoring::AlertSeverity) -> Self {
27        match severity {
28            monitoring::AlertSeverity::Critical => AlertSeverity::Critical,
29            monitoring::AlertSeverity::Warning => AlertSeverity::Warning,
30            monitoring::AlertSeverity::Info => AlertSeverity::Info,
31        }
32    }
33}
34
35#[derive(Debug, Clone, Serialize)]
36pub struct AlertNotification {
37    pub alert: HealthAlert,
38    pub notification_channels: Vec<NotificationChannel>,
39    pub escalation_level: EscalationLevel,
40    pub context: AlertContext,
41}
42
43#[derive(Debug, Clone, Serialize)]
44pub enum NotificationChannel {
45    Email(String),
46    Slack(String),
47    WebHook(String),
48    PagerDuty(String),
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
52pub enum EscalationLevel {
53    Low,
54    Medium,
55    High,
56    Critical,
57}
58
59#[derive(Debug, Clone, Serialize)]
60pub struct AlertContext {
61    pub incident_id: String,
62    pub affected_components: Vec<String>,
63    pub additional_info: HashMap<String, String>,
64    pub created_at: DateTime<Utc>,
65}
66
67pub struct AlertManager {
68    config: AlertConfig,
69    alert_tx: broadcast::Sender<AlertNotification>,
70    notification_handlers: Vec<NotificationHandlerType>,
71}
72
73#[derive(Clone)]
74pub struct AlertConfig {
75    pub alert_ttl: chrono::Duration,
76    pub max_alerts_per_window: usize,
77    pub notification_channels: Vec<NotificationChannel>,
78    pub escalation_policies: HashMap<AlertSeverity, EscalationPolicy>,
79}
80
81#[derive(Clone)]
82pub struct EscalationPolicy {
83    pub initial_delay: chrono::Duration,
84    pub repeat_interval: chrono::Duration,
85    pub max_escalations: usize,
86    pub notification_channels: Vec<NotificationChannel>,
87}
88
89#[async_trait]
90pub trait NotificationHandler: Send + Sync {
91    async fn send_notification(&self, notification: &AlertNotification) -> Result<(), NotificationError>;
92}
93
94#[derive(Debug, thiserror::Error)]
95pub enum NotificationError {
96    #[error("Failed to send notification: {0}")]
97    SendError(String),
98    
99    #[error("Channel configuration error: {0}")]
100    ConfigError(String),
101    
102    #[error("Rate limit exceeded")]
103    RateLimitExceeded,
104}
105
106#[derive(Clone)]
107pub enum NotificationHandlerType {
108    Email(crate::notification::EmailNotificationHandler),
109    Slack(crate::notification::SlackNotificationHandler),
110}
111
112impl NotificationHandlerType {
113    async fn send_notification(&self, notification: &AlertNotification) -> Result<(), NotificationError> {
114        match self {
115            Self::Email(handler) => handler.send_notification(notification).await,
116            Self::Slack(handler) => handler.send_notification(notification).await,
117        }
118    }
119}
120
121impl AlertManager {
122    pub fn new(config: AlertConfig) -> Self {
123        let (tx, _) = broadcast::channel(100);
124        Self {
125            config,
126            alert_tx: tx,
127            notification_handlers: Vec::new(),
128        }
129    }
130
131    pub fn register_handler(&mut self, handler: NotificationHandlerType) {
132        self.notification_handlers.push(handler);
133    }
134
135    pub async fn process_alert(&self, alert: HealthAlert) -> Result<(), NotificationError> {
136        let notification = self.create_notification(alert);
137        
138        // Alert'i broadcast et
139        let _ = self.alert_tx.send(notification.clone());
140
141        // Notification handler'ları çalıştır
142        for handler in &self.notification_handlers {
143            handler.send_notification(&notification).await?;
144        }
145
146        Ok(())
147    }
148
149    fn create_notification(&self, alert: HealthAlert) -> AlertNotification {
150        let severity = AlertSeverity::from(&alert.severity);
151        let channels = self.get_notification_channels(&severity);
152        
153        AlertNotification {
154            alert,
155            notification_channels: channels,
156            escalation_level: self.determine_escalation_level(&severity),
157            context: AlertContext {
158                incident_id: uuid::Uuid::new_v4().to_string(),
159                affected_components: Vec::new(),
160                additional_info: HashMap::new(),
161                created_at: Utc::now(),
162            },
163        }
164    }
165
166    fn get_notification_channels(&self, severity: &AlertSeverity) -> Vec<NotificationChannel> {
167        self.config
168            .escalation_policies
169            .get(severity)
170            .map(|policy| policy.notification_channels.clone())
171            .unwrap_or_else(|| self.config.notification_channels.clone())
172    }
173
174    fn determine_escalation_level(&self, severity: &AlertSeverity) -> EscalationLevel {
175        match severity {
176            AlertSeverity::Critical => EscalationLevel::Critical,
177            AlertSeverity::Warning => EscalationLevel::High,
178            AlertSeverity::Info => EscalationLevel::Low,
179        }
180    }
181}