ai_lib/error_handling/
monitoring.rs1use crate::error_handling::ErrorContext;
4use crate::metrics::Metrics;
5use crate::types::AiLibError;
6use serde::{Deserialize, Serialize};
7use std::sync::Arc;
8use std::time::Duration;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct ErrorThresholds {
13 pub error_rate_threshold: f64,
15 pub consecutive_errors: u32,
17 pub time_window: Duration,
19}
20
21impl Default for ErrorThresholds {
22 fn default() -> Self {
23 Self {
24 error_rate_threshold: 0.1, consecutive_errors: 5,
26 time_window: Duration::from_secs(60),
27 }
28 }
29}
30
31pub struct ErrorMonitor {
33 metrics: Arc<dyn Metrics>,
34 #[allow(dead_code)] alert_thresholds: ErrorThresholds,
36}
37
38impl ErrorMonitor {
39 pub fn new(metrics: Arc<dyn Metrics>, alert_thresholds: ErrorThresholds) -> Self {
41 Self {
42 metrics,
43 alert_thresholds,
44 }
45 }
46
47 pub async fn record_error(&self, error: &AiLibError, context: &ErrorContext) {
49 self.metrics.incr_counter("errors.total", 1).await;
51 self.metrics
52 .incr_counter(&format!("errors.{}", self.error_type_name(error)), 1)
53 .await;
54
55 if self.should_alert(error, context).await {
57 self.send_alert(error, context).await;
58 }
59 }
60
61 async fn should_alert(&self, error: &AiLibError, _context: &ErrorContext) -> bool {
63 matches!(
66 error,
67 AiLibError::RateLimitExceeded(_) | AiLibError::ProviderError(_)
68 )
69 }
70
71 async fn send_alert(&self, error: &AiLibError, context: &ErrorContext) {
73 let _ = (error, context);
77 }
78
79 fn error_type_name(&self, error: &AiLibError) -> String {
81 match error {
82 AiLibError::RateLimitExceeded(_) => "rate_limit".to_string(),
83 AiLibError::NetworkError(_) => "network".to_string(),
84 AiLibError::AuthenticationError(_) => "authentication".to_string(),
85 AiLibError::ProviderError(_) => "provider".to_string(),
86 AiLibError::TimeoutError(_) => "timeout".to_string(),
87 _ => "unknown".to_string(),
88 }
89 }
90}