scirs2_sparse/realtime_performance_monitor/
config.rs

1//! Configuration for Real-Time Performance Monitoring
2//!
3//! This module contains configuration structures and default settings
4//! for the real-time performance monitoring system.
5
6/// Configuration for real-time performance monitoring
7#[derive(Debug, Clone)]
8pub struct PerformanceMonitorConfig {
9    /// Monitoring interval in milliseconds
10    pub monitoring_interval_ms: u64,
11    /// Maximum number of performance samples to keep
12    pub max_samples: usize,
13    /// Enable adaptive tuning based on performance
14    pub adaptive_tuning: bool,
15    /// Performance threshold for adaptation triggers
16    pub adaptation_threshold: f64,
17    /// Enable real-time alerts
18    pub enable_alerts: bool,
19    /// Alert threshold for performance degradation
20    pub alert_threshold: f64,
21    /// Enable automatic optimization
22    pub auto_optimization: bool,
23    /// Optimization interval in seconds
24    pub optimization_interval_s: u64,
25    /// Enable performance prediction
26    pub enable_prediction: bool,
27    /// Prediction horizon in samples
28    pub prediction_horizon: usize,
29    /// Enable system metrics collection
30    pub enable_system_metrics: bool,
31    /// Enable anomaly detection
32    pub enable_anomaly_detection: bool,
33    /// Anomaly detection sensitivity (0.0 to 1.0)
34    pub anomaly_sensitivity: f64,
35    /// Maximum alert history to keep
36    pub max_alert_history: usize,
37    /// Maximum adaptation events to keep
38    pub max_adaptation_history: usize,
39}
40
41impl Default for PerformanceMonitorConfig {
42    fn default() -> Self {
43        Self {
44            monitoring_interval_ms: 100,
45            max_samples: 10000,
46            adaptive_tuning: true,
47            adaptation_threshold: 0.8,
48            enable_alerts: true,
49            alert_threshold: 0.5,
50            auto_optimization: true,
51            optimization_interval_s: 30,
52            enable_prediction: true,
53            prediction_horizon: 50,
54            enable_system_metrics: true,
55            enable_anomaly_detection: true,
56            anomaly_sensitivity: 0.7,
57            max_alert_history: 1000,
58            max_adaptation_history: 500,
59        }
60    }
61}
62
63impl PerformanceMonitorConfig {
64    /// Create a new configuration with default values
65    pub fn new() -> Self {
66        Default::default()
67    }
68
69    /// Create a lightweight configuration for minimal overhead
70    pub fn lightweight() -> Self {
71        Self {
72            monitoring_interval_ms: 500,
73            max_samples: 1000,
74            adaptive_tuning: false,
75            adaptation_threshold: 0.9,
76            enable_alerts: false,
77            alert_threshold: 0.3,
78            auto_optimization: false,
79            optimization_interval_s: 300,
80            enable_prediction: false,
81            prediction_horizon: 10,
82            enable_system_metrics: false,
83            enable_anomaly_detection: false,
84            anomaly_sensitivity: 0.5,
85            max_alert_history: 100,
86            max_adaptation_history: 50,
87        }
88    }
89
90    /// Create a high-performance configuration for detailed monitoring
91    pub fn high_performance() -> Self {
92        Self {
93            monitoring_interval_ms: 50,
94            max_samples: 50000,
95            adaptive_tuning: true,
96            adaptation_threshold: 0.7,
97            enable_alerts: true,
98            alert_threshold: 0.6,
99            auto_optimization: true,
100            optimization_interval_s: 10,
101            enable_prediction: true,
102            prediction_horizon: 100,
103            enable_system_metrics: true,
104            enable_anomaly_detection: true,
105            anomaly_sensitivity: 0.8,
106            max_alert_history: 5000,
107            max_adaptation_history: 2000,
108        }
109    }
110
111    /// Create a debugging configuration with extensive logging
112    pub fn debug() -> Self {
113        Self {
114            monitoring_interval_ms: 10,
115            max_samples: 100000,
116            adaptive_tuning: true,
117            adaptation_threshold: 0.6,
118            enable_alerts: true,
119            alert_threshold: 0.7,
120            auto_optimization: true,
121            optimization_interval_s: 5,
122            enable_prediction: true,
123            prediction_horizon: 200,
124            enable_system_metrics: true,
125            enable_anomaly_detection: true,
126            anomaly_sensitivity: 0.9,
127            max_alert_history: 10000,
128            max_adaptation_history: 5000,
129        }
130    }
131
132    /// Builder pattern methods for configuration
133    pub fn with_monitoring_interval_ms(mut self, interval: u64) -> Self {
134        self.monitoring_interval_ms = interval;
135        self
136    }
137
138    pub fn with_max_samples(mut self, max_samples: usize) -> Self {
139        self.max_samples = max_samples;
140        self
141    }
142
143    pub fn with_adaptive_tuning(mut self, enabled: bool) -> Self {
144        self.adaptive_tuning = enabled;
145        self
146    }
147
148    pub fn with_adaptation_threshold(mut self, threshold: f64) -> Self {
149        self.adaptation_threshold = threshold;
150        self
151    }
152
153    pub fn with_alerts(mut self, enabled: bool) -> Self {
154        self.enable_alerts = enabled;
155        self
156    }
157
158    pub fn with_alert_threshold(mut self, threshold: f64) -> Self {
159        self.alert_threshold = threshold;
160        self
161    }
162
163    pub fn with_auto_optimization(mut self, enabled: bool) -> Self {
164        self.auto_optimization = enabled;
165        self
166    }
167
168    pub fn with_optimization_interval_s(mut self, interval: u64) -> Self {
169        self.optimization_interval_s = interval;
170        self
171    }
172
173    pub fn with_prediction(mut self, enabled: bool) -> Self {
174        self.enable_prediction = enabled;
175        self
176    }
177
178    pub fn with_prediction_horizon(mut self, horizon: usize) -> Self {
179        self.prediction_horizon = horizon;
180        self
181    }
182
183    pub fn with_system_metrics(mut self, enabled: bool) -> Self {
184        self.enable_system_metrics = enabled;
185        self
186    }
187
188    pub fn with_anomaly_detection(mut self, enabled: bool) -> Self {
189        self.enable_anomaly_detection = enabled;
190        self
191    }
192
193    pub fn with_anomaly_sensitivity(mut self, sensitivity: f64) -> Self {
194        self.anomaly_sensitivity = sensitivity.clamp(0.0, 1.0);
195        self
196    }
197
198    /// Validate configuration parameters
199    pub fn validate(&self) -> Result<(), String> {
200        if self.monitoring_interval_ms == 0 {
201            return Err("Monitoring interval must be greater than 0".to_string());
202        }
203
204        if self.max_samples == 0 {
205            return Err("Max samples must be greater than 0".to_string());
206        }
207
208        if !(0.0..=1.0).contains(&self.adaptation_threshold) {
209            return Err("Adaptation threshold must be between 0.0 and 1.0".to_string());
210        }
211
212        if !(0.0..=1.0).contains(&self.alert_threshold) {
213            return Err("Alert threshold must be between 0.0 and 1.0".to_string());
214        }
215
216        if self.optimization_interval_s == 0 && self.auto_optimization {
217            return Err(
218                "Optimization interval must be greater than 0 when auto-optimization is enabled"
219                    .to_string(),
220            );
221        }
222
223        if self.prediction_horizon == 0 && self.enable_prediction {
224            return Err(
225                "Prediction horizon must be greater than 0 when prediction is enabled".to_string(),
226            );
227        }
228
229        if !(0.0..=1.0).contains(&self.anomaly_sensitivity) {
230            return Err("Anomaly sensitivity must be between 0.0 and 1.0".to_string());
231        }
232
233        if self.max_alert_history == 0 && self.enable_alerts {
234            return Err(
235                "Max alert history must be greater than 0 when alerts are enabled".to_string(),
236            );
237        }
238
239        if self.max_adaptation_history == 0 && self.adaptive_tuning {
240            return Err(
241                "Max adaptation history must be greater than 0 when adaptive tuning is enabled"
242                    .to_string(),
243            );
244        }
245
246        Ok(())
247    }
248
249    /// Get estimated memory usage in bytes
250    pub fn estimated_memory_usage(&self) -> usize {
251        let sample_size = std::mem::size_of::<super::metrics::PerformanceSample>();
252        let alert_size = std::mem::size_of::<super::alerts::Alert>();
253        let adaptation_size = 256; // Estimated size for adaptation events
254
255        self.max_samples * sample_size
256            + self.max_alert_history * alert_size
257            + self.max_adaptation_history * adaptation_size
258            + 8192 // Base overhead
259    }
260
261    /// Check if configuration is suitable for real-time operation
262    pub fn is_realtime_suitable(&self) -> bool {
263        // Real-time suitable if monitoring interval is reasonable
264        // and memory usage is not excessive
265        self.monitoring_interval_ms <= 1000 &&
266        self.estimated_memory_usage() <= 100 * 1024 * 1024 && // 100MB limit
267        self.max_samples <= 50000
268    }
269
270    /// Get recommended settings based on use case
271    pub fn recommended_for_use_case(use_case: UseCase) -> Self {
272        match use_case {
273            UseCase::Production => Self::default(),
274            UseCase::Development => Self::debug(),
275            UseCase::Testing => Self::lightweight(),
276            UseCase::Benchmarking => Self::high_performance(),
277            UseCase::LowResource => Self::lightweight().with_max_samples(500),
278        }
279    }
280}
281
282/// Different use cases for monitoring configuration
283#[derive(Debug, Clone, Copy)]
284pub enum UseCase {
285    /// Production environment with balanced monitoring
286    Production,
287    /// Development environment with detailed monitoring
288    Development,
289    /// Testing environment with minimal overhead
290    Testing,
291    /// Benchmarking with maximum detail
292    Benchmarking,
293    /// Low resource environment with minimal footprint
294    LowResource,
295}
296
297#[cfg(test)]
298mod tests {
299    use super::*;
300
301    #[test]
302    fn test_default_config() {
303        let config = PerformanceMonitorConfig::default();
304        assert!(config.validate().is_ok());
305        assert_eq!(config.monitoring_interval_ms, 100);
306        assert_eq!(config.max_samples, 10000);
307        assert!(config.adaptive_tuning);
308        assert!(config.enable_alerts);
309    }
310
311    #[test]
312    fn test_lightweight_config() {
313        let config = PerformanceMonitorConfig::lightweight();
314        assert!(config.validate().is_ok());
315        assert_eq!(config.monitoring_interval_ms, 500);
316        assert_eq!(config.max_samples, 1000);
317        assert!(!config.adaptive_tuning);
318        assert!(!config.enable_alerts);
319    }
320
321    #[test]
322    fn test_high_performance_config() {
323        let config = PerformanceMonitorConfig::high_performance();
324        assert!(config.validate().is_ok());
325        assert_eq!(config.monitoring_interval_ms, 50);
326        assert_eq!(config.max_samples, 50000);
327        assert!(config.adaptive_tuning);
328        assert!(config.enable_alerts);
329    }
330
331    #[test]
332    fn test_builder_pattern() {
333        let config = PerformanceMonitorConfig::new()
334            .with_monitoring_interval_ms(200)
335            .with_max_samples(5000)
336            .with_adaptive_tuning(false)
337            .with_alerts(false);
338
339        assert!(config.validate().is_ok());
340        assert_eq!(config.monitoring_interval_ms, 200);
341        assert_eq!(config.max_samples, 5000);
342        assert!(!config.adaptive_tuning);
343        assert!(!config.enable_alerts);
344    }
345
346    #[test]
347    fn test_config_validation() {
348        let mut config = PerformanceMonitorConfig::default();
349        assert!(config.validate().is_ok());
350
351        // Test invalid monitoring interval
352        config.monitoring_interval_ms = 0;
353        assert!(config.validate().is_err());
354
355        config.monitoring_interval_ms = 100;
356        config.max_samples = 0;
357        assert!(config.validate().is_err());
358
359        config.max_samples = 1000;
360        config.adaptation_threshold = 1.5;
361        assert!(config.validate().is_err());
362
363        config.adaptation_threshold = 0.8;
364        config.alert_threshold = -0.1;
365        assert!(config.validate().is_err());
366    }
367
368    #[test]
369    fn test_memory_usage_estimation() {
370        let config = PerformanceMonitorConfig::default();
371        let memory_usage = config.estimated_memory_usage();
372        assert!(memory_usage > 0);
373
374        let lightweight = PerformanceMonitorConfig::lightweight();
375        let lightweight_memory = lightweight.estimated_memory_usage();
376        assert!(lightweight_memory < memory_usage);
377    }
378
379    #[test]
380    fn test_realtime_suitability() {
381        let config = PerformanceMonitorConfig::default();
382        assert!(config.is_realtime_suitable());
383
384        let debug_config = PerformanceMonitorConfig::debug();
385        // Debug config might not be suitable for real-time due to high frequency
386        let _ = debug_config.is_realtime_suitable(); // Result depends on implementation
387    }
388
389    #[test]
390    fn test_use_case_recommendations() {
391        let production = PerformanceMonitorConfig::recommended_for_use_case(UseCase::Production);
392        assert!(production.validate().is_ok());
393
394        let development = PerformanceMonitorConfig::recommended_for_use_case(UseCase::Development);
395        assert!(development.validate().is_ok());
396
397        let testing = PerformanceMonitorConfig::recommended_for_use_case(UseCase::Testing);
398        assert!(testing.validate().is_ok());
399
400        let benchmarking =
401            PerformanceMonitorConfig::recommended_for_use_case(UseCase::Benchmarking);
402        assert!(benchmarking.validate().is_ok());
403
404        let low_resource = PerformanceMonitorConfig::recommended_for_use_case(UseCase::LowResource);
405        assert!(low_resource.validate().is_ok());
406        assert_eq!(low_resource.max_samples, 500);
407    }
408
409    #[test]
410    fn test_anomaly_sensitivity_clamping() {
411        let config = PerformanceMonitorConfig::new().with_anomaly_sensitivity(1.5); // Should be clamped to 1.0
412        assert_eq!(config.anomaly_sensitivity, 1.0);
413
414        let config = PerformanceMonitorConfig::new().with_anomaly_sensitivity(-0.1); // Should be clamped to 0.0
415        assert_eq!(config.anomaly_sensitivity, 0.0);
416    }
417}