Skip to main content

litellm_rs/monitoring/
system.rs

1//! Core MonitoringSystem implementation
2
3use crate::config::models::monitoring::MonitoringConfig;
4use crate::storage::StorageLayer;
5use crate::utils::error::gateway_error::Result;
6use std::sync::Arc;
7use std::time::{Duration, Instant};
8
9use tracing::{debug, info, warn};
10
11use super::types::*;
12use super::{alerts, metrics};
13
14/// Main monitoring system
15#[derive(Clone)]
16pub struct MonitoringSystem {
17    /// Monitoring configuration
18    pub(super) _config: Arc<MonitoringConfig>,
19    /// Storage layer for persistence
20    pub(super) _storage: Arc<StorageLayer>,
21    /// Metrics collector
22    pub(super) metrics: Arc<metrics::MetricsCollector>,
23    /// Alert manager
24    pub(super) alerts: Option<Arc<alerts::AlertManager>>,
25    /// System start time
26    pub(super) start_time: Instant,
27}
28
29impl MonitoringSystem {
30    /// Create a new monitoring system
31    pub async fn new(config: &MonitoringConfig, storage: Arc<StorageLayer>) -> Result<Self> {
32        info!("Initializing monitoring system");
33
34        let config = Arc::new(config.clone());
35
36        // Initialize metrics collector
37        let metrics = Arc::new(metrics::MetricsCollector::new(&config).await?);
38
39        // Initialize alert manager (if enabled)
40        let alerts = None; // NOTE: alerting config not yet added to MonitoringConfig
41
42        info!("Monitoring system initialized successfully");
43
44        Ok(Self {
45            _config: config,
46            _storage: storage,
47            metrics,
48            alerts,
49            start_time: Instant::now(),
50        })
51    }
52
53    /// Start the monitoring system
54    pub async fn start(&self) -> Result<()> {
55        info!("Starting monitoring system");
56
57        // Start metrics collection
58        self.metrics.start().await?;
59
60        // Start alert manager
61        if let Some(alerts) = &self.alerts {
62            alerts.start().await?;
63        }
64
65        // Start background tasks
66        self.start_background_tasks().await?;
67
68        info!("Monitoring system started successfully");
69        Ok(())
70    }
71
72    /// Stop the monitoring system
73    pub async fn stop(&self) -> Result<()> {
74        info!("Stopping monitoring system");
75
76        // Stop metrics collection
77        self.metrics.stop().await?;
78
79        // Stop alert manager
80        if let Some(alerts) = &self.alerts {
81            alerts.stop().await?;
82        }
83
84        info!("Monitoring system stopped");
85        Ok(())
86    }
87
88    /// Get current system metrics
89    pub async fn get_metrics(&self) -> Result<SystemMetrics> {
90        debug!("Collecting system metrics");
91
92        let timestamp = chrono::Utc::now();
93
94        // Collect metrics from various sources
95        let requests = self.collect_request_metrics().await?;
96        let providers = self.collect_provider_metrics().await?;
97        let system = self.collect_system_metrics().await?;
98        let errors = self.collect_error_metrics().await?;
99        let performance = self.collect_performance_metrics().await?;
100
101        Ok(SystemMetrics {
102            timestamp,
103            requests,
104            providers,
105            system,
106            errors,
107            performance,
108        })
109    }
110
111    /// Record a request metric
112    pub async fn record_request(
113        &self,
114        method: &str,
115        path: &str,
116        status_code: u16,
117        response_time: Duration,
118        user_id: Option<uuid::Uuid>,
119        api_key_id: Option<uuid::Uuid>,
120    ) -> Result<()> {
121        self.metrics
122            .record_request(
123                method,
124                path,
125                status_code,
126                response_time,
127                user_id,
128                api_key_id,
129            )
130            .await
131    }
132
133    /// Record a provider request metric
134    pub async fn record_provider_request(
135        &self,
136        provider: &str,
137        model: &str,
138        tokens_used: u32,
139        cost: f64,
140        response_time: Duration,
141        success: bool,
142    ) -> Result<()> {
143        self.metrics
144            .record_provider_request(provider, model, tokens_used, cost, response_time, success)
145            .await
146    }
147
148    /// Record an error
149    pub async fn record_error(
150        &self,
151        error_type: &str,
152        error_message: &str,
153        context: Option<serde_json::Value>,
154    ) -> Result<()> {
155        self.metrics
156            .record_error(error_type, error_message, context)
157            .await
158    }
159
160    /// Send an alert
161    pub async fn send_alert(&self, alert: Alert) -> Result<()> {
162        if let Some(alerts) = &self.alerts {
163            alerts.send_alert(alert).await
164        } else {
165            warn!("Alert manager not configured, skipping alert");
166            Ok(())
167        }
168    }
169
170    /// Get system uptime
171    pub fn get_uptime(&self) -> Duration {
172        self.start_time.elapsed()
173    }
174
175    /// Collect request metrics
176    pub(super) async fn collect_request_metrics(&self) -> Result<MonitoringRequestMetrics> {
177        self.metrics.get_request_metrics().await
178    }
179
180    /// Collect provider metrics
181    pub(super) async fn collect_provider_metrics(&self) -> Result<ProviderMetrics> {
182        self.metrics.get_provider_metrics().await
183    }
184
185    /// Collect system resource metrics
186    pub(super) async fn collect_system_metrics(&self) -> Result<SystemResourceMetrics> {
187        self.metrics.get_system_metrics().await
188    }
189
190    /// Collect error metrics
191    pub(super) async fn collect_error_metrics(&self) -> Result<ErrorMetrics> {
192        self.metrics.get_error_metrics().await
193    }
194
195    /// Collect performance metrics
196    pub(super) async fn collect_performance_metrics(&self) -> Result<PerformanceMetrics> {
197        self.metrics.get_performance_metrics().await
198    }
199}