1use anyhow::Result;
7use serde::{Deserialize, Serialize};
8use std::collections::{HashMap, VecDeque};
9use std::sync::Arc;
10use std::time::{Duration, SystemTime};
11use tokio::sync::{broadcast, Mutex as AsyncMutex, RwLock as AsyncRwLock};
12use tokio::time::interval;
13use tracing::{error, info};
14
15use crate::ai_query_predictor::AIQueryPredictor;
16use crate::performance::{PerformanceStats, PerformanceTracker};
17
18#[derive(Debug, Clone)]
20pub struct PredictiveAnalyticsConfig {
21 pub enable_real_time_monitoring: bool,
22 pub enable_anomaly_detection: bool,
23 pub enable_capacity_planning: bool,
24 pub enable_trend_analysis: bool,
25 pub enable_predictive_scaling: bool,
26 pub monitoring_interval: Duration,
27 pub prediction_window: Duration,
28 pub anomaly_threshold: f64,
29 pub trend_window: Duration,
30 pub capacity_threshold: f64,
31 pub alert_config: AlertConfig,
32 pub metrics_retention: Duration,
33 pub sampling_rate: f64,
34}
35
36impl Default for PredictiveAnalyticsConfig {
37 fn default() -> Self {
38 Self {
39 enable_real_time_monitoring: true,
40 enable_anomaly_detection: true,
41 enable_capacity_planning: true,
42 enable_trend_analysis: true,
43 enable_predictive_scaling: true,
44 monitoring_interval: Duration::from_secs(10),
45 prediction_window: Duration::from_secs(300),
46 anomaly_threshold: 2.0, trend_window: Duration::from_secs(3600),
48 capacity_threshold: 0.8, alert_config: AlertConfig::default(),
50 metrics_retention: Duration::from_secs(86400 * 7), sampling_rate: 1.0, }
53 }
54}
55
56#[derive(Debug, Clone)]
58pub struct AlertConfig {
59 pub enable_alerts: bool,
60 pub alert_channels: Vec<AlertChannel>,
61 pub severity_thresholds: HashMap<AlertType, f64>,
62 pub cooldown_period: Duration,
63 pub escalation_rules: Vec<EscalationRule>,
64}
65
66impl Default for AlertConfig {
67 fn default() -> Self {
68 let mut severity_thresholds = HashMap::new();
69 severity_thresholds.insert(AlertType::HighLatency, 1000.0); severity_thresholds.insert(AlertType::HighErrorRate, 0.05); severity_thresholds.insert(AlertType::HighMemoryUsage, 0.9); severity_thresholds.insert(AlertType::AnomalyDetected, 3.0); Self {
75 enable_alerts: true,
76 alert_channels: vec![AlertChannel::Log, AlertChannel::Metrics],
77 severity_thresholds,
78 cooldown_period: Duration::from_secs(300),
79 escalation_rules: Vec::new(),
80 }
81 }
82}
83
84#[derive(Debug, Clone)]
86pub enum AlertChannel {
87 Log,
88 Metrics,
89 Webhook { url: String },
90 Email { recipients: Vec<String> },
91 Slack { webhook_url: String },
92 PagerDuty { integration_key: String },
93}
94
95#[derive(Debug, Clone, Hash, Eq, PartialEq)]
97pub enum AlertType {
98 HighLatency,
99 HighErrorRate,
100 HighMemoryUsage,
101 HighCPUUsage,
102 AnomalyDetected,
103 CapacityExceeded,
104 TrendDegrading,
105 PredictiveFailure,
106}
107
108#[derive(Debug, Clone)]
110pub struct EscalationRule {
111 pub condition: EscalationCondition,
112 pub action: EscalationAction,
113 pub delay: Duration,
114}
115
116#[derive(Debug, Clone)]
117pub enum EscalationCondition {
118 TimeElapsed(Duration),
119 SeverityLevel(AlertSeverity),
120 RepeatCount(usize),
121}
122
123#[derive(Debug, Clone)]
124pub enum EscalationAction {
125 NotifyChannel(AlertChannel),
126 AutoScale { target_capacity: f64 },
127 FailoverToBackup,
128 EnableCircuitBreaker,
129}
130
131#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
133pub enum AlertSeverity {
134 Info,
135 Warning,
136 Critical,
137 Emergency,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct PredictiveMetrics {
143 pub current_metrics: PerformanceStats,
144 pub predicted_metrics: PredictedPerformance,
145 pub anomalies: Vec<Anomaly>,
146 pub trends: TrendAnalysis,
147 pub capacity_forecast: CapacityForecast,
148 pub risk_assessment: RiskAssessment,
149 pub timestamp: SystemTime,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct PredictedPerformance {
155 pub next_5_minutes: PerformanceForecast,
156 pub next_15_minutes: PerformanceForecast,
157 pub next_hour: PerformanceForecast,
158 pub confidence_scores: HashMap<String, f64>,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
163pub struct PerformanceForecast {
164 pub predicted_qps: f64,
165 pub predicted_latency: Duration,
166 pub predicted_error_rate: f64,
167 pub predicted_memory_usage: f64,
168 pub predicted_cpu_usage: f64,
169 pub confidence_interval: (f64, f64),
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize)]
174pub struct Anomaly {
175 pub metric_name: String,
176 pub current_value: f64,
177 pub expected_value: f64,
178 pub deviation_score: f64,
179 pub severity: AlertSeverity,
180 pub detected_at: SystemTime,
181 pub duration: Duration,
182 pub likely_cause: Option<String>,
183 pub suggested_action: Option<String>,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct TrendAnalysis {
189 pub performance_trend: TrendDirection,
190 pub trend_strength: f64,
191 pub trend_duration: Duration,
192 pub seasonal_patterns: Vec<SeasonalPattern>,
193 pub change_points: Vec<ChangePoint>,
194 pub forecast_accuracy: f64,
195}
196
197#[derive(Debug, Clone, Serialize, Deserialize)]
199pub enum TrendDirection {
200 Improving,
201 Stable,
202 Degrading,
203 Volatile,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
208pub struct SeasonalPattern {
209 pub pattern_type: SeasonalType,
210 pub period: Duration,
211 pub amplitude: f64,
212 pub confidence: f64,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
216pub enum SeasonalType {
217 Hourly,
218 Daily,
219 Weekly,
220 Monthly,
221 Custom { period: Duration },
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
226pub struct ChangePoint {
227 pub timestamp: SystemTime,
228 pub metric: String,
229 pub magnitude: f64,
230 pub confidence: f64,
231 pub likely_cause: Option<String>,
232}
233
234#[derive(Debug, Clone, Serialize, Deserialize)]
236pub struct CapacityForecast {
237 pub current_utilization: f64,
238 pub predicted_peak: CapacityPrediction,
239 pub time_to_capacity: Option<Duration>,
240 pub scaling_recommendations: Vec<ScalingRecommendation>,
241 pub resource_bottlenecks: Vec<ResourceBottleneck>,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct CapacityPrediction {
247 pub utilization: f64,
248 pub timestamp: SystemTime,
249 pub confidence: f64,
250}
251
252#[derive(Debug, Clone, Serialize, Deserialize)]
254pub struct ScalingRecommendation {
255 pub resource_type: ResourceType,
256 pub action: ScalingAction,
257 pub urgency: ScalingUrgency,
258 pub estimated_impact: f64,
259 pub cost_estimate: Option<f64>,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
263pub enum ResourceType {
264 CPU,
265 Memory,
266 Storage,
267 Network,
268 Instances,
269}
270
271#[derive(Debug, Clone, Serialize, Deserialize)]
272pub enum ScalingAction {
273 ScaleUp { factor: f64 },
274 ScaleDown { factor: f64 },
275 ScaleOut { instances: usize },
276 ScaleIn { instances: usize },
277 Optimize { recommendation: String },
278}
279
280#[derive(Debug, Clone, Serialize, Deserialize)]
281pub enum ScalingUrgency {
282 Low,
283 Medium,
284 High,
285 Critical,
286}
287
288#[derive(Debug, Clone, Serialize, Deserialize)]
290pub struct ResourceBottleneck {
291 pub resource: ResourceType,
292 pub current_utilization: f64,
293 pub impact_score: f64,
294 pub mitigation_suggestions: Vec<String>,
295}
296
297#[derive(Debug, Clone, Serialize, Deserialize)]
299pub struct RiskAssessment {
300 pub overall_risk_score: f64,
301 pub risk_factors: Vec<RiskFactor>,
302 pub mitigation_strategies: Vec<MitigationStrategy>,
303 pub sla_breach_probability: f64,
304}
305
306#[derive(Debug, Clone, Serialize, Deserialize)]
308pub struct RiskFactor {
309 pub factor_type: RiskType,
310 pub probability: f64,
311 pub impact: f64,
312 pub risk_score: f64,
313 pub description: String,
314}
315
316#[derive(Debug, Clone, Serialize, Deserialize)]
317pub enum RiskType {
318 CapacityRisk,
319 PerformanceRisk,
320 AvailabilityRisk,
321 SecurityRisk,
322 DataRisk,
323}
324
325#[derive(Debug, Clone, Serialize, Deserialize)]
327pub struct MitigationStrategy {
328 pub strategy_name: String,
329 pub effectiveness: f64,
330 pub implementation_cost: f64,
331 pub time_to_implement: Duration,
332 pub description: String,
333}
334
335pub struct PredictiveAnalyticsEngine {
337 config: PredictiveAnalyticsConfig,
338 ai_predictor: Arc<AIQueryPredictor>,
339 performance_tracker: Arc<PerformanceTracker>,
340 metrics_history: Arc<AsyncRwLock<VecDeque<PredictiveMetrics>>>,
341 anomaly_detector: Arc<AsyncRwLock<AnomalyDetector>>,
342 trend_analyzer: Arc<AsyncRwLock<TrendAnalyzer>>,
343 capacity_planner: Arc<AsyncRwLock<CapacityPlanner>>,
344 #[allow(dead_code)]
345 alert_manager: Arc<AsyncMutex<AlertManager>>,
346 monitoring_tasks: Arc<AsyncMutex<Vec<tokio::task::JoinHandle<()>>>>,
347 alert_sender: broadcast::Sender<Alert>,
348}
349
350impl PredictiveAnalyticsEngine {
351 pub fn new(
353 config: PredictiveAnalyticsConfig,
354 ai_predictor: Arc<AIQueryPredictor>,
355 performance_tracker: Arc<PerformanceTracker>,
356 ) -> (Self, broadcast::Receiver<Alert>) {
357 let (alert_sender, alert_receiver) = broadcast::channel(1000);
358
359 let engine = Self {
360 config: config.clone(),
361 ai_predictor,
362 performance_tracker,
363 metrics_history: Arc::new(AsyncRwLock::new(VecDeque::new())),
364 anomaly_detector: Arc::new(AsyncRwLock::new(AnomalyDetector::new(&config))),
365 trend_analyzer: Arc::new(AsyncRwLock::new(TrendAnalyzer::new(&config))),
366 capacity_planner: Arc::new(AsyncRwLock::new(CapacityPlanner::new(&config))),
367 alert_manager: Arc::new(AsyncMutex::new(AlertManager::new(config.alert_config))),
368 monitoring_tasks: Arc::new(AsyncMutex::new(Vec::new())),
369 alert_sender,
370 };
371
372 (engine, alert_receiver)
373 }
374
375 pub async fn start(&self) -> Result<()> {
377 info!("Starting predictive analytics engine");
378
379 let mut tasks = self.monitoring_tasks.lock().await;
380
381 if self.config.enable_real_time_monitoring {
383 let task = self.start_real_time_monitoring().await?;
384 tasks.push(task);
385 }
386
387 if self.config.enable_anomaly_detection {
389 let task = self.start_anomaly_detection().await?;
390 tasks.push(task);
391 }
392
393 if self.config.enable_trend_analysis {
395 let task = self.start_trend_analysis().await?;
396 tasks.push(task);
397 }
398
399 if self.config.enable_capacity_planning {
401 let task = self.start_capacity_planning().await?;
402 tasks.push(task);
403 }
404
405 info!("Predictive analytics engine started successfully");
406 Ok(())
407 }
408
409 async fn start_real_time_monitoring(&self) -> Result<tokio::task::JoinHandle<()>> {
411 let config = self.config.clone();
412 let performance_tracker = Arc::clone(&self.performance_tracker);
413 let metrics_history = Arc::clone(&self.metrics_history);
414 let ai_predictor = Arc::clone(&self.ai_predictor);
415 let alert_sender = self.alert_sender.clone();
416
417 let task = tokio::spawn(async move {
418 let mut interval = interval(config.monitoring_interval);
419
420 loop {
421 interval.tick().await;
422
423 match Self::collect_predictive_metrics(&performance_tracker, &ai_predictor, &config)
424 .await
425 {
426 Ok(metrics) => {
427 {
429 let mut history = metrics_history.write().await;
430 history.push_back(metrics.clone());
431
432 let max_entries = (config.metrics_retention.as_secs()
434 / config.monitoring_interval.as_secs())
435 as usize;
436 while history.len() > max_entries {
437 history.pop_front();
438 }
439 }
440
441 if let Err(e) = Self::check_immediate_alerts(&metrics, &alert_sender).await
443 {
444 error!("Failed to check immediate alerts: {}", e);
445 }
446 }
447 Err(e) => {
448 error!("Failed to collect predictive metrics: {}", e);
449 }
450 }
451 }
452 });
453
454 Ok(task)
455 }
456
457 async fn start_anomaly_detection(&self) -> Result<tokio::task::JoinHandle<()>> {
459 let config = self.config.clone();
460 let anomaly_detector = Arc::clone(&self.anomaly_detector);
461 let metrics_history = Arc::clone(&self.metrics_history);
462 let alert_sender = self.alert_sender.clone();
463
464 let task = tokio::spawn(async move {
465 let mut interval = interval(config.monitoring_interval * 2);
466
467 loop {
468 interval.tick().await;
469
470 match Self::detect_anomalies(&anomaly_detector, &metrics_history).await {
471 Ok(anomalies) => {
472 for anomaly in anomalies {
473 let alert = Alert {
474 alert_type: AlertType::AnomalyDetected,
475 severity: anomaly.severity.clone(),
476 message: format!("Anomaly detected in {}: current={:.2}, expected={:.2}, deviation={:.2}",
477 anomaly.metric_name, anomaly.current_value,
478 anomaly.expected_value, anomaly.deviation_score),
479 timestamp: SystemTime::now(),
480 metadata: HashMap::new(),
481 };
482
483 if let Err(e) = alert_sender.send(alert) {
484 error!("Failed to send anomaly alert: {}", e);
485 }
486 }
487 }
488 Err(e) => {
489 error!("Failed to detect anomalies: {}", e);
490 }
491 }
492 }
493 });
494
495 Ok(task)
496 }
497
498 async fn start_trend_analysis(&self) -> Result<tokio::task::JoinHandle<()>> {
500 let config = self.config.clone();
501 let trend_analyzer = Arc::clone(&self.trend_analyzer);
502 let metrics_history = Arc::clone(&self.metrics_history);
503 let alert_sender = self.alert_sender.clone();
504
505 let task = tokio::spawn(async move {
506 let mut interval = interval(config.trend_window / 4);
507
508 loop {
509 interval.tick().await;
510
511 match Self::analyze_trends(&trend_analyzer, &metrics_history).await {
512 Ok(trend_analysis) => {
513 if matches!(trend_analysis.performance_trend, TrendDirection::Degrading)
514 && trend_analysis.trend_strength > 0.7
515 {
516 let alert = Alert {
517 alert_type: AlertType::TrendDegrading,
518 severity: AlertSeverity::Warning,
519 message: format!(
520 "Performance trend degrading with strength {:.2}",
521 trend_analysis.trend_strength
522 ),
523 timestamp: SystemTime::now(),
524 metadata: HashMap::new(),
525 };
526
527 if let Err(e) = alert_sender.send(alert) {
528 error!("Failed to send trend alert: {}", e);
529 }
530 }
531 }
532 Err(e) => {
533 error!("Failed to analyze trends: {}", e);
534 }
535 }
536 }
537 });
538
539 Ok(task)
540 }
541
542 async fn start_capacity_planning(&self) -> Result<tokio::task::JoinHandle<()>> {
544 let config = self.config.clone();
545 let capacity_planner = Arc::clone(&self.capacity_planner);
546 let metrics_history = Arc::clone(&self.metrics_history);
547 let alert_sender = self.alert_sender.clone();
548
549 let task = tokio::spawn(async move {
550 let mut interval = interval(config.prediction_window);
551
552 loop {
553 interval.tick().await;
554
555 match Self::plan_capacity(&capacity_planner, &metrics_history, &config).await {
556 Ok(capacity_forecast) => {
557 if capacity_forecast.current_utilization > config.capacity_threshold {
558 let alert = Alert {
559 alert_type: AlertType::CapacityExceeded,
560 severity: AlertSeverity::Critical,
561 message: format!(
562 "Capacity threshold exceeded: {:.2}%",
563 capacity_forecast.current_utilization * 100.0
564 ),
565 timestamp: SystemTime::now(),
566 metadata: HashMap::new(),
567 };
568
569 if let Err(e) = alert_sender.send(alert) {
570 error!("Failed to send capacity alert: {}", e);
571 }
572 }
573 }
574 Err(e) => {
575 error!("Failed to plan capacity: {}", e);
576 }
577 }
578 }
579 });
580
581 Ok(task)
582 }
583
584 async fn collect_predictive_metrics(
586 _performance_tracker: &Arc<PerformanceTracker>,
587 _ai_predictor: &Arc<AIQueryPredictor>,
588 _config: &PredictiveAnalyticsConfig,
589 ) -> Result<PredictiveMetrics> {
590 let base_exec_time = Duration::from_millis(120); let variance_factor = 0.2; Ok(PredictiveMetrics {
595 current_metrics: PerformanceStats {
596 total_requests: 1000,
597 total_errors: 10,
598 avg_execution_time: base_exec_time,
599 p50_execution_time: Duration::from_millis(
600 (base_exec_time.as_millis() as f64 * 0.8) as u64,
601 ),
602 p95_execution_time: Duration::from_millis(
603 (base_exec_time.as_millis() as f64 * (1.0 + variance_factor * 2.0)) as u64,
604 ),
605 p99_execution_time: Duration::from_millis(
606 (base_exec_time.as_millis() as f64 * (1.0 + variance_factor * 4.0)) as u64,
607 ),
608 cache_hit_ratio: 0.85,
609 queries_per_second: 10.0,
610 error_rate: 0.01,
611 most_expensive_queries: Vec::new(),
612 slowest_fields: Vec::new(),
613 client_stats: HashMap::new(),
614 },
615 predicted_metrics: PredictedPerformance {
616 next_5_minutes: PerformanceForecast {
617 predicted_qps: 12.0,
618 predicted_latency: Duration::from_millis(110),
619 predicted_error_rate: 0.012,
620 predicted_memory_usage: 0.7,
621 predicted_cpu_usage: 0.6,
622 confidence_interval: (0.8, 0.95),
623 },
624 next_15_minutes: PerformanceForecast {
625 predicted_qps: 15.0,
626 predicted_latency: Duration::from_millis(120),
627 predicted_error_rate: 0.015,
628 predicted_memory_usage: 0.75,
629 predicted_cpu_usage: 0.65,
630 confidence_interval: (0.7, 0.9),
631 },
632 next_hour: PerformanceForecast {
633 predicted_qps: 20.0,
634 predicted_latency: Duration::from_millis(150),
635 predicted_error_rate: 0.02,
636 predicted_memory_usage: 0.8,
637 predicted_cpu_usage: 0.7,
638 confidence_interval: (0.6, 0.85),
639 },
640 confidence_scores: HashMap::new(),
641 },
642 anomalies: Vec::new(),
643 trends: TrendAnalysis {
644 performance_trend: TrendDirection::Stable,
645 trend_strength: 0.3,
646 trend_duration: Duration::from_secs(3600),
647 seasonal_patterns: Vec::new(),
648 change_points: Vec::new(),
649 forecast_accuracy: 0.85,
650 },
651 capacity_forecast: CapacityForecast {
652 current_utilization: 0.6,
653 predicted_peak: CapacityPrediction {
654 utilization: 0.8,
655 timestamp: SystemTime::now(),
656 confidence: 0.7,
657 },
658 time_to_capacity: Some(Duration::from_secs(7200)),
659 scaling_recommendations: Vec::new(),
660 resource_bottlenecks: Vec::new(),
661 },
662 risk_assessment: RiskAssessment {
663 overall_risk_score: 0.3,
664 risk_factors: Vec::new(),
665 mitigation_strategies: Vec::new(),
666 sla_breach_probability: 0.05,
667 },
668 timestamp: SystemTime::now(),
669 })
670 }
671
672 async fn check_immediate_alerts(
674 _metrics: &PredictiveMetrics,
675 _alert_sender: &broadcast::Sender<Alert>,
676 ) -> Result<()> {
677 Ok(())
679 }
680
681 async fn detect_anomalies(
683 _anomaly_detector: &Arc<AsyncRwLock<AnomalyDetector>>,
684 _metrics_history: &Arc<AsyncRwLock<VecDeque<PredictiveMetrics>>>,
685 ) -> Result<Vec<Anomaly>> {
686 Ok(Vec::new())
688 }
689
690 async fn analyze_trends(
692 _trend_analyzer: &Arc<AsyncRwLock<TrendAnalyzer>>,
693 _metrics_history: &Arc<AsyncRwLock<VecDeque<PredictiveMetrics>>>,
694 ) -> Result<TrendAnalysis> {
695 Ok(TrendAnalysis {
697 performance_trend: TrendDirection::Stable,
698 trend_strength: 0.3,
699 trend_duration: Duration::from_secs(3600),
700 seasonal_patterns: Vec::new(),
701 change_points: Vec::new(),
702 forecast_accuracy: 0.85,
703 })
704 }
705
706 async fn plan_capacity(
708 _capacity_planner: &Arc<AsyncRwLock<CapacityPlanner>>,
709 _metrics_history: &Arc<AsyncRwLock<VecDeque<PredictiveMetrics>>>,
710 _config: &PredictiveAnalyticsConfig,
711 ) -> Result<CapacityForecast> {
712 Ok(CapacityForecast {
714 current_utilization: 0.6,
715 predicted_peak: CapacityPrediction {
716 utilization: 0.8,
717 timestamp: SystemTime::now(),
718 confidence: 0.7,
719 },
720 time_to_capacity: Some(Duration::from_secs(7200)),
721 scaling_recommendations: Vec::new(),
722 resource_bottlenecks: Vec::new(),
723 })
724 }
725
726 pub async fn get_current_metrics(&self) -> Result<Option<PredictiveMetrics>> {
728 let history = self.metrics_history.read().await;
729 Ok(history.back().cloned())
730 }
731
732 pub async fn get_metrics_history(&self, duration: Duration) -> Result<Vec<PredictiveMetrics>> {
734 let history = self.metrics_history.read().await;
735 let cutoff = SystemTime::now() - duration;
736
737 Ok(history
738 .iter()
739 .filter(|m| m.timestamp >= cutoff)
740 .cloned()
741 .collect())
742 }
743}
744
745#[derive(Debug, Clone)]
747pub struct Alert {
748 pub alert_type: AlertType,
749 pub severity: AlertSeverity,
750 pub message: String,
751 pub timestamp: SystemTime,
752 pub metadata: HashMap<String, String>,
753}
754
755#[derive(Debug)]
757pub struct AnomalyDetector {
758 #[allow(dead_code)]
759 threshold: f64,
760 #[allow(dead_code)]
761 window_size: usize,
762 #[allow(dead_code)]
763 statistical_models: HashMap<String, StatisticalModel>,
764}
765
766impl AnomalyDetector {
767 pub fn new(config: &PredictiveAnalyticsConfig) -> Self {
768 Self {
769 threshold: config.anomaly_threshold,
770 window_size: 100,
771 statistical_models: HashMap::new(),
772 }
773 }
774}
775
776#[derive(Debug)]
778pub struct TrendAnalyzer {
779 #[allow(dead_code)]
780 window_size: Duration,
781 #[allow(dead_code)]
782 seasonal_detection: bool,
783 #[allow(dead_code)]
784 change_point_detection: bool,
785}
786
787impl TrendAnalyzer {
788 pub fn new(config: &PredictiveAnalyticsConfig) -> Self {
789 Self {
790 window_size: config.trend_window,
791 seasonal_detection: true,
792 change_point_detection: true,
793 }
794 }
795}
796
797#[derive(Debug)]
799pub struct CapacityPlanner {
800 #[allow(dead_code)]
801 prediction_horizon: Duration,
802 #[allow(dead_code)]
803 scaling_policies: Vec<ScalingPolicy>,
804}
805
806impl CapacityPlanner {
807 pub fn new(config: &PredictiveAnalyticsConfig) -> Self {
808 Self {
809 prediction_horizon: config.prediction_window,
810 scaling_policies: Vec::new(),
811 }
812 }
813}
814
815#[derive(Debug)]
817pub struct AlertManager {
818 #[allow(dead_code)]
819 config: AlertConfig,
820 #[allow(dead_code)]
821 active_alerts: HashMap<String, Alert>,
822 #[allow(dead_code)]
823 cooldown_timers: HashMap<String, SystemTime>,
824}
825
826impl AlertManager {
827 pub fn new(config: AlertConfig) -> Self {
828 Self {
829 config,
830 active_alerts: HashMap::new(),
831 cooldown_timers: HashMap::new(),
832 }
833 }
834}
835
836#[derive(Debug)]
838pub struct StatisticalModel {
839 #[allow(dead_code)]
840 mean: f64,
841 #[allow(dead_code)]
842 std_dev: f64,
843 #[allow(dead_code)]
844 observations: VecDeque<f64>,
845 #[allow(dead_code)]
846 model_type: ModelType,
847}
848
849#[derive(Debug)]
850pub enum ModelType {
851 ZScore,
852 IsolationForest,
853 LSTM,
854 MovingAverage,
855}
856
857#[derive(Debug)]
859pub struct ScalingPolicy {
860 pub metric: String,
861 pub threshold: f64,
862 pub action: ScalingAction,
863 pub cooldown: Duration,
864}