1use crate::{
8 error::QuantRS2Result,
9 hardware_compilation::{HardwarePlatform, NativeGateType},
10 qubit::QubitId,
11};
12use num_complex::Complex64;
13use std::{
14 collections::{HashMap, HashSet, VecDeque},
15 fmt,
16 sync::{Arc, RwLock},
17 thread,
18 time::{Duration, SystemTime},
19};
20
21#[derive(Debug, Clone)]
23pub struct MonitoringConfig {
24 pub monitoring_interval: Duration,
26 pub data_retention_period: Duration,
28 pub alert_thresholds: AlertThresholds,
30 pub enabled_metrics: HashSet<MetricType>,
32 pub platform_configs: HashMap<HardwarePlatform, PlatformMonitoringConfig>,
34 pub export_settings: ExportSettings,
36}
37
38#[derive(Debug, Clone)]
40pub struct AlertThresholds {
41 pub max_gate_error_rate: f64,
43 pub max_readout_error_rate: f64,
45 pub min_coherence_time: Duration,
47 pub max_calibration_drift: f64,
49 pub max_temperature: f64,
51 pub max_queue_depth: usize,
53 pub max_execution_time: Duration,
55}
56
57#[derive(Debug, Clone)]
59pub struct PlatformMonitoringConfig {
60 pub platform: HardwarePlatform,
62 pub monitored_metrics: HashSet<MetricType>,
64 pub sampling_rates: HashMap<MetricType, Duration>,
66 pub custom_thresholds: HashMap<String, f64>,
68 pub connection_settings: HashMap<String, String>,
70}
71
72#[derive(Debug, Clone)]
74pub struct ExportSettings {
75 pub enable_export: bool,
77 pub export_formats: Vec<ExportFormat>,
79 pub export_destinations: Vec<ExportDestination>,
81 pub export_frequency: Duration,
83 pub compression_enabled: bool,
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum ExportFormat {
90 JSON,
91 CSV,
92 Parquet,
93 InfluxDB,
94 Prometheus,
95 Custom,
96}
97
98#[derive(Debug, Clone)]
100pub enum ExportDestination {
101 File(String),
102 Database(DatabaseConfig),
103 Cloud(CloudConfig),
104 Stream(StreamConfig),
105}
106
107#[derive(Debug, Clone)]
109pub struct DatabaseConfig {
110 pub connection_string: String,
111 pub table_name: String,
112 pub credentials: HashMap<String, String>,
113}
114
115#[derive(Debug, Clone)]
117pub struct CloudConfig {
118 pub provider: String,
119 pub endpoint: String,
120 pub credentials: HashMap<String, String>,
121}
122
123#[derive(Debug, Clone)]
125pub struct StreamConfig {
126 pub stream_type: String,
127 pub endpoint: String,
128 pub topic: String,
129}
130
131#[derive(Debug, Clone, PartialEq, Eq, Hash)]
133pub enum MetricType {
134 GateErrorRate,
136 GateFidelity,
137 GateExecutionTime,
138 GateCalibrationDrift,
139
140 QubitCoherenceTime,
142 QubitReadoutError,
143 QubitTemperature,
144 QubitCrosstalk,
145
146 SystemUptime,
148 QueueDepth,
149 Throughput,
150 Latency,
151
152 EnvironmentalTemperature,
154 MagneticField,
155 Vibration,
156 ElectromagneticNoise,
157
158 CPUUsage,
160 MemoryUsage,
161 NetworkLatency,
162 StorageUsage,
163
164 Custom(String),
166}
167
168#[derive(Debug)]
170pub struct RealtimeMonitor {
171 config: MonitoringConfig,
173 collectors: Arc<RwLock<HashMap<HardwarePlatform, Box<dyn MetricCollector>>>>,
175 data_store: Arc<RwLock<RealtimeDataStore>>,
177 analytics_engine: Arc<RwLock<AnalyticsEngine>>,
179 alert_manager: Arc<RwLock<AlertManager>>,
181 optimization_advisor: Arc<RwLock<OptimizationAdvisor>>,
183 dashboard: Arc<RwLock<PerformanceDashboard>>,
185 export_manager: Arc<RwLock<ExportManager>>,
187 monitoring_status: Arc<RwLock<MonitoringStatus>>,
189}
190
191pub trait MetricCollector: std::fmt::Debug + Send + Sync {
193 fn collect_metrics(&self) -> QuantRS2Result<Vec<MetricMeasurement>>;
195
196 fn supported_metrics(&self) -> HashSet<MetricType>;
198
199 fn platform(&self) -> HardwarePlatform;
201
202 fn initialize(&mut self) -> QuantRS2Result<()>;
204
205 fn is_connected(&self) -> bool;
207
208 fn disconnect(&mut self) -> QuantRS2Result<()>;
210}
211
212#[derive(Debug, Clone)]
214pub struct MetricMeasurement {
215 pub metric_type: MetricType,
217 pub value: MetricValue,
219 pub timestamp: SystemTime,
221 pub qubit: Option<QubitId>,
223 pub gate_type: Option<NativeGateType>,
225 pub metadata: HashMap<String, String>,
227 pub uncertainty: Option<f64>,
229}
230
231#[derive(Debug, Clone)]
233pub enum MetricValue {
234 Float(f64),
235 Integer(i64),
236 Boolean(bool),
237 String(String),
238 Array(Vec<f64>),
239 Complex(Complex64),
240 Duration(Duration),
241}
242
243#[derive(Debug)]
245pub struct RealtimeDataStore {
246 time_series: HashMap<MetricType, VecDeque<MetricMeasurement>>,
248 aggregated_stats: HashMap<MetricType, AggregatedStats>,
250 retention_settings: HashMap<MetricType, Duration>,
252 current_data_size: usize,
254 max_data_size: usize,
256}
257
258#[derive(Debug, Clone)]
260pub struct AggregatedStats {
261 pub mean: f64,
263 pub std_dev: f64,
265 pub min: f64,
267 pub max: f64,
269 pub median: f64,
271 pub p95: f64,
273 pub p99: f64,
275 pub sample_count: usize,
277 pub last_updated: SystemTime,
279}
280
281#[derive(Debug)]
283pub struct AnalyticsEngine {
284 trend_analyzers: HashMap<MetricType, Box<dyn TrendAnalyzer>>,
286 anomaly_detectors: HashMap<MetricType, Box<dyn AnomalyDetector>>,
288 correlation_analyzers: Vec<Box<dyn CorrelationAnalyzer>>,
290 predictive_models: HashMap<MetricType, Box<dyn PredictiveModel>>,
292 analysis_cache: HashMap<String, AnalysisResult>,
294}
295
296pub trait TrendAnalyzer: std::fmt::Debug + Send + Sync {
298 fn analyze_trend(&self, data: &[MetricMeasurement]) -> QuantRS2Result<TrendAnalysis>;
300
301 fn name(&self) -> &str;
303}
304
305pub trait AnomalyDetector: std::fmt::Debug + Send + Sync {
307 fn detect_anomalies(&self, data: &[MetricMeasurement]) -> QuantRS2Result<Vec<Anomaly>>;
309
310 fn name(&self) -> &str;
312
313 fn confidence_threshold(&self) -> f64;
315}
316
317pub trait CorrelationAnalyzer: std::fmt::Debug + Send + Sync {
319 fn analyze_correlations(
321 &self,
322 data: &HashMap<MetricType, Vec<MetricMeasurement>>,
323 ) -> QuantRS2Result<Vec<Correlation>>;
324
325 fn name(&self) -> &str;
327}
328
329pub trait PredictiveModel: std::fmt::Debug + Send + Sync {
331 fn predict(
333 &self,
334 historical_data: &[MetricMeasurement],
335 horizon: Duration,
336 ) -> QuantRS2Result<Prediction>;
337
338 fn update(&mut self, new_data: &[MetricMeasurement]) -> QuantRS2Result<()>;
340
341 fn name(&self) -> &str;
343
344 fn accuracy(&self) -> f64;
346}
347
348#[derive(Debug, Clone)]
350pub struct TrendAnalysis {
351 pub direction: TrendDirection,
353 pub strength: f64,
355 pub duration: Duration,
357 pub significance: f64,
359 pub extrapolation: Option<f64>,
361}
362
363#[derive(Debug, Clone, Copy, PartialEq, Eq)]
365pub enum TrendDirection {
366 Increasing,
367 Decreasing,
368 Stable,
369 Oscillating,
370 Unknown,
371}
372
373#[derive(Debug, Clone)]
375pub struct Anomaly {
376 pub anomaly_type: AnomalyType,
378 pub confidence: f64,
380 pub metric: MetricType,
382 pub timestamp: SystemTime,
384 pub description: String,
386 pub suggested_actions: Vec<String>,
388}
389
390#[derive(Debug, Clone, Copy, PartialEq, Eq)]
392pub enum AnomalyType {
393 Outlier,
394 PatternBreak,
395 Drift,
396 Spike,
397 PerformanceDegradation,
398 SystemFailure,
399}
400
401#[derive(Debug, Clone)]
403pub struct Correlation {
404 pub metric1: MetricType,
406 pub metric2: MetricType,
408 pub coefficient: f64,
410 pub significance: f64,
412 pub correlation_type: CorrelationType,
414 pub time_lag: Option<Duration>,
416}
417
418#[derive(Debug, Clone, Copy, PartialEq, Eq)]
420pub enum CorrelationType {
421 Positive,
422 Negative,
423 NonLinear,
424 Causal,
425 Spurious,
426}
427
428#[derive(Debug, Clone)]
430pub struct Prediction {
431 pub predicted_values: Vec<(SystemTime, f64)>,
433 pub confidence_intervals: Vec<(f64, f64)>,
435 pub accuracy_estimate: f64,
437 pub model_name: String,
439 pub horizon: Duration,
441}
442
443#[derive(Debug, Clone)]
445pub struct AnalysisResult {
446 pub analysis_type: String,
448 pub result_data: HashMap<String, String>,
450 pub confidence: f64,
452 pub timestamp: SystemTime,
454}
455
456#[derive(Debug)]
458pub struct AlertManager {
459 active_alerts: HashMap<String, Alert>,
461 alert_rules: Vec<AlertRule>,
463 alert_handlers: Vec<Box<dyn AlertHandler>>,
465 alert_history: VecDeque<Alert>,
467 suppression_rules: Vec<SuppressionRule>,
469}
470
471#[derive(Debug, Clone)]
473pub struct Alert {
474 pub id: String,
476 pub level: AlertLevel,
478 pub message: String,
480 pub affected_metrics: Vec<MetricType>,
482 pub timestamp: SystemTime,
484 pub source: String,
486 pub suggested_actions: Vec<String>,
488 pub status: AlertStatus,
490}
491
492#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
494pub enum AlertLevel {
495 Info,
496 Warning,
497 Critical,
498 Emergency,
499}
500
501#[derive(Debug, Clone, Copy, PartialEq, Eq)]
503pub enum AlertStatus {
504 Active,
505 Acknowledged,
506 Resolved,
507 Suppressed,
508}
509
510#[derive(Debug, Clone)]
512pub struct AlertRule {
513 pub id: String,
515 pub name: String,
517 pub condition: AlertCondition,
519 pub alert_level: AlertLevel,
521 pub message_template: String,
523 pub cooldown_period: Duration,
525}
526
527#[derive(Debug, Clone)]
529pub enum AlertCondition {
530 Threshold {
532 metric: MetricType,
533 operator: ComparisonOperator,
534 threshold: f64,
535 duration: Duration,
536 },
537 RateOfChange {
539 metric: MetricType,
540 rate_threshold: f64,
541 time_window: Duration,
542 },
543 AnomalyDetected {
545 metric: MetricType,
546 confidence_threshold: f64,
547 },
548 Complex {
550 expression: String,
551 required_metrics: Vec<MetricType>,
552 },
553}
554
555#[derive(Debug, Clone, Copy, PartialEq, Eq)]
557pub enum ComparisonOperator {
558 GreaterThan,
559 LessThan,
560 Equal,
561 NotEqual,
562 GreaterThanOrEqual,
563 LessThanOrEqual,
564}
565
566pub trait AlertHandler: std::fmt::Debug + Send + Sync {
568 fn handle_alert(&self, alert: &Alert) -> QuantRS2Result<()>;
570
571 fn name(&self) -> &str;
573
574 fn can_handle(&self, level: AlertLevel) -> bool;
576}
577
578#[derive(Debug, Clone)]
580pub struct SuppressionRule {
581 pub id: String,
583 pub condition: SuppressionCondition,
585 pub duration: Duration,
587 pub description: String,
589}
590
591#[derive(Debug, Clone)]
593pub enum SuppressionCondition {
594 AlertType(String),
596 MaintenanceWindow(SystemTime, SystemTime),
598 MetricPattern(MetricType, String),
600}
601
602#[derive(Debug)]
604pub struct OptimizationAdvisor {
605 optimization_strategies: HashMap<String, Box<dyn OptimizationStrategy>>,
607 recommendation_engine: RecommendationEngine,
609 active_recommendations: Vec<OptimizationRecommendation>,
611 recommendation_history: VecDeque<OptimizationRecommendation>,
613}
614
615pub trait OptimizationStrategy: std::fmt::Debug + Send + Sync {
617 fn analyze(&self, data: &RealtimeDataStore) -> QuantRS2Result<Vec<OptimizationRecommendation>>;
619
620 fn name(&self) -> &str;
622
623 fn priority(&self) -> u32;
625}
626
627#[derive(Debug, Clone)]
629pub struct OptimizationRecommendation {
630 pub id: String,
632 pub recommendation_type: RecommendationType,
634 pub description: String,
636 pub affected_components: Vec<String>,
638 pub expected_improvement: ExpectedImprovement,
640 pub implementation_difficulty: DifficultyLevel,
642 pub priority: RecommendationPriority,
644 pub timestamp: SystemTime,
646}
647
648#[derive(Debug, Clone, Copy, PartialEq, Eq)]
650pub enum RecommendationType {
651 GateOptimization,
652 CalibrationAdjustment,
653 CircuitOptimization,
654 ResourceReallocation,
655 EnvironmentalAdjustment,
656 MaintenanceRequired,
657 UpgradeRecommendation,
658}
659
660#[derive(Debug, Clone)]
662pub struct ExpectedImprovement {
663 pub fidelity_improvement: Option<f64>,
665 pub speed_improvement: Option<f64>,
667 pub error_rate_reduction: Option<f64>,
669 pub resource_savings: Option<f64>,
671}
672
673#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
675pub enum DifficultyLevel {
676 Easy,
677 Medium,
678 Hard,
679 ExpertRequired,
680}
681
682#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
684pub enum RecommendationPriority {
685 Low,
686 Medium,
687 High,
688 Critical,
689}
690
691#[derive(Debug)]
693pub struct RecommendationEngine {
694 ml_models: HashMap<String, Box<dyn MLModel>>,
696 rule_based_rules: Vec<RecommendationRule>,
698 knowledge_base: KnowledgeBase,
700}
701
702pub trait MLModel: std::fmt::Debug + Send + Sync {
704 fn train(&mut self, training_data: &[TrainingExample]) -> QuantRS2Result<()>;
706
707 fn predict(
709 &self,
710 input_data: &[MetricMeasurement],
711 ) -> QuantRS2Result<Vec<OptimizationRecommendation>>;
712
713 fn accuracy(&self) -> f64;
715
716 fn name(&self) -> &str;
718}
719
720#[derive(Debug, Clone)]
722pub struct TrainingExample {
723 pub input_metrics: Vec<MetricMeasurement>,
725 pub expected_recommendation: OptimizationRecommendation,
727 pub actual_outcome: Option<OutcomeMetrics>,
729}
730
731#[derive(Debug, Clone)]
733pub struct OutcomeMetrics {
734 pub performance_improvement: f64,
736 pub implementation_success: bool,
738 pub implementation_time: Duration,
740 pub side_effects: Vec<String>,
742}
743
744#[derive(Debug, Clone)]
746pub struct RecommendationRule {
747 pub id: String,
749 pub condition: String,
751 pub recommendation_template: OptimizationRecommendation,
753 pub weight: f64,
755}
756
757#[derive(Debug)]
759pub struct KnowledgeBase {
760 best_practices: HashMap<String, BestPractice>,
762 issue_solutions: HashMap<String, Solution>,
764 platform_knowledge: HashMap<HardwarePlatform, PlatformKnowledge>,
766}
767
768#[derive(Debug, Clone)]
770pub struct BestPractice {
771 pub id: String,
773 pub description: String,
775 pub applicable_platforms: Vec<HardwarePlatform>,
777 pub expected_benefits: Vec<String>,
779 pub implementation_steps: Vec<String>,
781}
782
783#[derive(Debug, Clone)]
785pub struct Solution {
786 pub id: String,
788 pub problem_description: String,
790 pub solution_description: String,
792 pub success_rate: f64,
794 pub complexity: DifficultyLevel,
796}
797
798#[derive(Debug, Clone)]
800pub struct PlatformKnowledge {
801 pub platform: HardwarePlatform,
803 pub known_limitations: Vec<String>,
805 pub optimization_opportunities: Vec<String>,
807 pub common_failure_modes: Vec<String>,
809 pub vendor_tips: Vec<String>,
811}
812
813#[derive(Debug)]
815pub struct PerformanceDashboard {
816 widgets: HashMap<String, Box<dyn DashboardWidget>>,
818 layout: DashboardLayout,
820 update_frequency: Duration,
822 dashboard_state: DashboardState,
824}
825
826pub trait DashboardWidget: std::fmt::Debug + Send + Sync {
828 fn render(&self, data: &RealtimeDataStore) -> QuantRS2Result<WidgetData>;
830
831 fn get_config(&self) -> WidgetConfig;
833
834 fn update_config(&mut self, config: WidgetConfig) -> QuantRS2Result<()>;
836}
837
838#[derive(Debug, Clone)]
840pub struct WidgetData {
841 pub widget_type: String,
843 pub data: HashMap<String, String>,
845 pub visualization_hints: Vec<String>,
847 pub timestamp: SystemTime,
849}
850
851#[derive(Debug, Clone)]
853pub struct WidgetConfig {
854 pub title: String,
856 pub size: (u32, u32),
858 pub position: (u32, u32),
860 pub refresh_rate: Duration,
862 pub data_source: String,
864 pub display_options: HashMap<String, String>,
866}
867
868#[derive(Debug, Clone)]
870pub struct DashboardLayout {
871 pub layout_type: LayoutType,
873 pub grid_dimensions: (u32, u32),
875 pub widget_positions: HashMap<String, (u32, u32)>,
877}
878
879#[derive(Debug, Clone, Copy, PartialEq, Eq)]
881pub enum LayoutType {
882 Grid,
883 Flexible,
884 Stacked,
885 Tabbed,
886}
887
888#[derive(Debug, Clone)]
890pub struct DashboardState {
891 pub active_widgets: HashSet<String>,
893 pub last_update: SystemTime,
895 pub mode: DashboardMode,
897}
898
899#[derive(Debug, Clone, Copy, PartialEq, Eq)]
901pub enum DashboardMode {
902 Monitoring,
903 Analysis,
904 Debugging,
905 Maintenance,
906}
907
908#[derive(Debug)]
910pub struct ExportManager {
911 exporters: HashMap<ExportFormat, Box<dyn DataExporter>>,
913 export_queue: VecDeque<ExportTask>,
915 export_stats: ExportStatistics,
917}
918
919pub trait DataExporter: std::fmt::Debug + Send + Sync {
921 fn export(
923 &self,
924 data: &[MetricMeasurement],
925 destination: &ExportDestination,
926 ) -> QuantRS2Result<()>;
927
928 fn format(&self) -> ExportFormat;
930
931 fn validate_config(&self, destination: &ExportDestination) -> QuantRS2Result<()>;
933}
934
935#[derive(Debug, Clone)]
937pub struct ExportTask {
938 pub id: String,
940 pub data_range: (SystemTime, SystemTime),
942 pub format: ExportFormat,
944 pub destination: ExportDestination,
946 pub priority: TaskPriority,
948 pub created: SystemTime,
950}
951
952#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
954pub enum TaskPriority {
955 Low,
956 Normal,
957 High,
958 Urgent,
959}
960
961#[derive(Debug, Clone)]
963pub struct ExportStatistics {
964 pub total_exports: u64,
966 pub failed_exports: u64,
968 pub average_export_time: Duration,
970 pub total_data_volume: u64,
972 pub last_export_time: SystemTime,
974}
975
976#[derive(Debug, Clone)]
978pub struct MonitoringStatus {
979 pub overall_status: SystemStatus,
981 pub platform_statuses: HashMap<HardwarePlatform, PlatformStatus>,
983 pub active_collectors: usize,
985 pub total_data_points: u64,
987 pub active_alerts: usize,
989 pub uptime: Duration,
991}
992
993#[derive(Debug, Clone, Copy, PartialEq, Eq)]
995pub enum SystemStatus {
996 Healthy,
997 Degraded,
998 Critical,
999 Offline,
1000}
1001
1002#[derive(Debug, Clone)]
1004pub struct PlatformStatus {
1005 pub connection_status: ConnectionStatus,
1007 pub last_data_collection: SystemTime,
1009 pub collection_rate: f64,
1011 pub error_rate: f64,
1013 pub platform_metrics: HashMap<String, f64>,
1015}
1016
1017#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1019pub enum ConnectionStatus {
1020 Connected,
1021 Disconnected,
1022 Reconnecting,
1023 Error,
1024}
1025
1026impl RealtimeMonitor {
1027 pub fn new(config: MonitoringConfig) -> QuantRS2Result<Self> {
1029 Ok(Self {
1030 config: config.clone(),
1031 collectors: Arc::new(RwLock::new(HashMap::new())),
1032 data_store: Arc::new(RwLock::new(RealtimeDataStore::new(
1033 config.data_retention_period,
1034 ))),
1035 analytics_engine: Arc::new(RwLock::new(AnalyticsEngine::new())),
1036 alert_manager: Arc::new(RwLock::new(AlertManager::new(config.alert_thresholds))),
1037 optimization_advisor: Arc::new(RwLock::new(OptimizationAdvisor::new())),
1038 dashboard: Arc::new(RwLock::new(PerformanceDashboard::new())),
1039 export_manager: Arc::new(RwLock::new(ExportManager::new(config.export_settings))),
1040 monitoring_status: Arc::new(RwLock::new(MonitoringStatus::new())),
1041 })
1042 }
1043
1044 pub fn start_monitoring(&self) -> QuantRS2Result<()> {
1046 self.initialize_collectors()?;
1048
1049 self.start_data_collection_threads()?;
1051
1052 self.start_analytics_engine()?;
1054
1055 self.start_alert_processing()?;
1057
1058 self.start_export_processing()?;
1060
1061 {
1063 let mut status = self.monitoring_status.write().unwrap();
1064 status.overall_status = SystemStatus::Healthy;
1065 }
1066
1067 Ok(())
1068 }
1069
1070 pub fn stop_monitoring(&self) -> QuantRS2Result<()> {
1072 Ok(())
1074 }
1075
1076 pub fn register_collector(
1078 &self,
1079 platform: HardwarePlatform,
1080 collector: Box<dyn MetricCollector>,
1081 ) -> QuantRS2Result<()> {
1082 let mut collectors = self.collectors.write().unwrap();
1083 collectors.insert(platform, collector);
1084 Ok(())
1085 }
1086
1087 pub fn get_current_metrics(
1089 &self,
1090 metric_types: Option<Vec<MetricType>>,
1091 ) -> QuantRS2Result<Vec<MetricMeasurement>> {
1092 let data_store = self.data_store.read().unwrap();
1093
1094 let mut results = Vec::new();
1095
1096 match metric_types {
1097 Some(types) => {
1098 for metric_type in types {
1099 if let Some(time_series) = data_store.time_series.get(&metric_type) {
1100 if let Some(latest) = time_series.back() {
1101 results.push(latest.clone());
1102 }
1103 }
1104 }
1105 }
1106 None => {
1107 for time_series in data_store.time_series.values() {
1108 if let Some(latest) = time_series.back() {
1109 results.push(latest.clone());
1110 }
1111 }
1112 }
1113 }
1114
1115 Ok(results)
1116 }
1117
1118 pub fn get_historical_metrics(
1120 &self,
1121 metric_type: MetricType,
1122 start_time: SystemTime,
1123 end_time: SystemTime,
1124 ) -> QuantRS2Result<Vec<MetricMeasurement>> {
1125 let data_store = self.data_store.read().unwrap();
1126
1127 if let Some(time_series) = data_store.time_series.get(&metric_type) {
1128 let filtered: Vec<MetricMeasurement> = time_series
1129 .iter()
1130 .filter(|measurement| {
1131 measurement.timestamp >= start_time && measurement.timestamp <= end_time
1132 })
1133 .cloned()
1134 .collect();
1135
1136 Ok(filtered)
1137 } else {
1138 Ok(Vec::new())
1139 }
1140 }
1141
1142 pub fn get_aggregated_stats(
1144 &self,
1145 metric_type: MetricType,
1146 ) -> QuantRS2Result<Option<AggregatedStats>> {
1147 let data_store = self.data_store.read().unwrap();
1148 Ok(data_store.aggregated_stats.get(&metric_type).cloned())
1149 }
1150
1151 pub fn get_active_alerts(&self) -> QuantRS2Result<Vec<Alert>> {
1153 let alert_manager = self.alert_manager.read().unwrap();
1154 Ok(alert_manager.active_alerts.values().cloned().collect())
1155 }
1156
1157 pub fn get_optimization_recommendations(
1159 &self,
1160 ) -> QuantRS2Result<Vec<OptimizationRecommendation>> {
1161 let optimization_advisor = self.optimization_advisor.read().unwrap();
1162 Ok(optimization_advisor.active_recommendations.clone())
1163 }
1164
1165 pub fn get_monitoring_status(&self) -> MonitoringStatus {
1167 self.monitoring_status.read().unwrap().clone()
1168 }
1169
1170 pub fn collect_metrics_now(&self) -> QuantRS2Result<usize> {
1172 let collectors = self.collectors.read().unwrap();
1173 let mut total_metrics = 0;
1174
1175 for collector in collectors.values() {
1176 let metrics = collector.collect_metrics()?;
1177 total_metrics += metrics.len();
1178
1179 self.store_metrics(metrics)?;
1181 }
1182
1183 Ok(total_metrics)
1184 }
1185
1186 pub fn update_analytics(&self) -> QuantRS2Result<()> {
1188 let data_store = self.data_store.read().unwrap();
1189 let analytics = self.analytics_engine.write().unwrap();
1190
1191 for (metric_type, time_series) in &data_store.time_series {
1193 if let Some(analyzer) = analytics.trend_analyzers.get(metric_type) {
1194 let data: Vec<MetricMeasurement> = time_series.iter().cloned().collect();
1195 let _trend = analyzer.analyze_trend(&data)?;
1196 }
1198 }
1199
1200 Ok(())
1201 }
1202
1203 fn initialize_collectors(&self) -> QuantRS2Result<()> {
1205 for (platform, platform_config) in &self.config.platform_configs {
1207 let collector = self.create_collector_for_platform(*platform, platform_config)?;
1209 self.register_collector(*platform, collector)?;
1210 }
1211 Ok(())
1212 }
1213
1214 fn create_collector_for_platform(
1215 &self,
1216 platform: HardwarePlatform,
1217 config: &PlatformMonitoringConfig,
1218 ) -> QuantRS2Result<Box<dyn MetricCollector>> {
1219 match platform {
1220 HardwarePlatform::Superconducting => {
1221 Ok(Box::new(SuperconductingCollector::new(config.clone())))
1222 }
1223 HardwarePlatform::TrappedIon => Ok(Box::new(TrappedIonCollector::new(config.clone()))),
1224 HardwarePlatform::Photonic => Ok(Box::new(PhotonicCollector::new(config.clone()))),
1225 HardwarePlatform::NeutralAtom => {
1226 Ok(Box::new(NeutralAtomCollector::new(config.clone())))
1227 }
1228 _ => Ok(Box::new(GenericCollector::new(config.clone()))),
1229 }
1230 }
1231
1232 fn start_data_collection_threads(&self) -> QuantRS2Result<()> {
1233 let collectors = Arc::clone(&self.collectors);
1235 let data_store = Arc::clone(&self.data_store);
1236 let monitoring_interval = self.config.monitoring_interval;
1237
1238 thread::spawn(move || loop {
1239 thread::sleep(monitoring_interval);
1240
1241 let collectors_guard = collectors.read().unwrap();
1242 for collector in collectors_guard.values() {
1243 if let Ok(metrics) = collector.collect_metrics() {
1244 let mut store = data_store.write().unwrap();
1245 for metric in metrics {
1246 store.add_measurement(metric);
1247 }
1248 }
1249 }
1250 });
1251
1252 Ok(())
1253 }
1254
1255 fn start_analytics_engine(&self) -> QuantRS2Result<()> {
1256 Ok(())
1258 }
1259
1260 fn start_alert_processing(&self) -> QuantRS2Result<()> {
1261 Ok(())
1263 }
1264
1265 fn start_export_processing(&self) -> QuantRS2Result<()> {
1266 Ok(())
1268 }
1269
1270 fn store_metrics(&self, metrics: Vec<MetricMeasurement>) -> QuantRS2Result<()> {
1271 let mut data_store = self.data_store.write().unwrap();
1272 for metric in metrics {
1273 data_store.add_measurement(metric);
1274 }
1275 Ok(())
1276 }
1277}
1278
1279#[derive(Debug)]
1281struct SuperconductingCollector {
1282 config: PlatformMonitoringConfig,
1283 connected: bool,
1284}
1285
1286impl SuperconductingCollector {
1287 fn new(config: PlatformMonitoringConfig) -> Self {
1288 Self {
1289 config,
1290 connected: false,
1291 }
1292 }
1293}
1294
1295impl MetricCollector for SuperconductingCollector {
1296 fn collect_metrics(&self) -> QuantRS2Result<Vec<MetricMeasurement>> {
1297 let mut metrics = Vec::new();
1299
1300 metrics.push(MetricMeasurement {
1302 metric_type: MetricType::GateErrorRate,
1303 value: MetricValue::Float(0.001),
1304 timestamp: SystemTime::now(),
1305 qubit: Some(QubitId::new(0)),
1306 gate_type: Some(NativeGateType::CNOT),
1307 metadata: HashMap::new(),
1308 uncertainty: Some(0.0001),
1309 });
1310
1311 metrics.push(MetricMeasurement {
1313 metric_type: MetricType::QubitCoherenceTime,
1314 value: MetricValue::Duration(Duration::from_micros(100)),
1315 timestamp: SystemTime::now(),
1316 qubit: Some(QubitId::new(0)),
1317 gate_type: None,
1318 metadata: HashMap::new(),
1319 uncertainty: Some(0.01),
1320 });
1321
1322 Ok(metrics)
1323 }
1324
1325 fn supported_metrics(&self) -> HashSet<MetricType> {
1326 let mut metrics = HashSet::new();
1327 metrics.insert(MetricType::GateErrorRate);
1328 metrics.insert(MetricType::QubitCoherenceTime);
1329 metrics.insert(MetricType::QubitReadoutError);
1330 metrics.insert(MetricType::QubitTemperature);
1331 metrics
1332 }
1333
1334 fn platform(&self) -> HardwarePlatform {
1335 HardwarePlatform::Superconducting
1336 }
1337
1338 fn initialize(&mut self) -> QuantRS2Result<()> {
1339 self.connected = true;
1340 Ok(())
1341 }
1342
1343 fn is_connected(&self) -> bool {
1344 self.connected
1345 }
1346
1347 fn disconnect(&mut self) -> QuantRS2Result<()> {
1348 self.connected = false;
1349 Ok(())
1350 }
1351}
1352
1353#[derive(Debug)]
1355struct TrappedIonCollector {
1356 config: PlatformMonitoringConfig,
1357 connected: bool,
1358}
1359
1360impl TrappedIonCollector {
1361 fn new(config: PlatformMonitoringConfig) -> Self {
1362 Self {
1363 config,
1364 connected: false,
1365 }
1366 }
1367}
1368
1369impl MetricCollector for TrappedIonCollector {
1370 fn collect_metrics(&self) -> QuantRS2Result<Vec<MetricMeasurement>> {
1371 Ok(vec![])
1372 }
1373
1374 fn supported_metrics(&self) -> HashSet<MetricType> {
1375 HashSet::new()
1376 }
1377
1378 fn platform(&self) -> HardwarePlatform {
1379 HardwarePlatform::TrappedIon
1380 }
1381
1382 fn initialize(&mut self) -> QuantRS2Result<()> {
1383 self.connected = true;
1384 Ok(())
1385 }
1386
1387 fn is_connected(&self) -> bool {
1388 self.connected
1389 }
1390
1391 fn disconnect(&mut self) -> QuantRS2Result<()> {
1392 self.connected = false;
1393 Ok(())
1394 }
1395}
1396
1397#[derive(Debug)]
1398struct PhotonicCollector {
1399 config: PlatformMonitoringConfig,
1400 connected: bool,
1401}
1402
1403impl PhotonicCollector {
1404 fn new(config: PlatformMonitoringConfig) -> Self {
1405 Self {
1406 config,
1407 connected: false,
1408 }
1409 }
1410}
1411
1412impl MetricCollector for PhotonicCollector {
1413 fn collect_metrics(&self) -> QuantRS2Result<Vec<MetricMeasurement>> {
1414 Ok(vec![])
1415 }
1416
1417 fn supported_metrics(&self) -> HashSet<MetricType> {
1418 HashSet::new()
1419 }
1420
1421 fn platform(&self) -> HardwarePlatform {
1422 HardwarePlatform::Photonic
1423 }
1424
1425 fn initialize(&mut self) -> QuantRS2Result<()> {
1426 self.connected = true;
1427 Ok(())
1428 }
1429
1430 fn is_connected(&self) -> bool {
1431 self.connected
1432 }
1433
1434 fn disconnect(&mut self) -> QuantRS2Result<()> {
1435 self.connected = false;
1436 Ok(())
1437 }
1438}
1439
1440#[derive(Debug)]
1441struct NeutralAtomCollector {
1442 config: PlatformMonitoringConfig,
1443 connected: bool,
1444}
1445
1446impl NeutralAtomCollector {
1447 fn new(config: PlatformMonitoringConfig) -> Self {
1448 Self {
1449 config,
1450 connected: false,
1451 }
1452 }
1453}
1454
1455impl MetricCollector for NeutralAtomCollector {
1456 fn collect_metrics(&self) -> QuantRS2Result<Vec<MetricMeasurement>> {
1457 Ok(vec![])
1458 }
1459
1460 fn supported_metrics(&self) -> HashSet<MetricType> {
1461 HashSet::new()
1462 }
1463
1464 fn platform(&self) -> HardwarePlatform {
1465 HardwarePlatform::NeutralAtom
1466 }
1467
1468 fn initialize(&mut self) -> QuantRS2Result<()> {
1469 self.connected = true;
1470 Ok(())
1471 }
1472
1473 fn is_connected(&self) -> bool {
1474 self.connected
1475 }
1476
1477 fn disconnect(&mut self) -> QuantRS2Result<()> {
1478 self.connected = false;
1479 Ok(())
1480 }
1481}
1482
1483#[derive(Debug)]
1484struct GenericCollector {
1485 config: PlatformMonitoringConfig,
1486 connected: bool,
1487}
1488
1489impl GenericCollector {
1490 fn new(config: PlatformMonitoringConfig) -> Self {
1491 Self {
1492 config,
1493 connected: false,
1494 }
1495 }
1496}
1497
1498impl MetricCollector for GenericCollector {
1499 fn collect_metrics(&self) -> QuantRS2Result<Vec<MetricMeasurement>> {
1500 Ok(vec![])
1501 }
1502
1503 fn supported_metrics(&self) -> HashSet<MetricType> {
1504 HashSet::new()
1505 }
1506
1507 fn platform(&self) -> HardwarePlatform {
1508 HardwarePlatform::Universal
1509 }
1510
1511 fn initialize(&mut self) -> QuantRS2Result<()> {
1512 self.connected = true;
1513 Ok(())
1514 }
1515
1516 fn is_connected(&self) -> bool {
1517 self.connected
1518 }
1519
1520 fn disconnect(&mut self) -> QuantRS2Result<()> {
1521 self.connected = false;
1522 Ok(())
1523 }
1524}
1525
1526impl RealtimeDataStore {
1528 fn new(_retention_period: Duration) -> Self {
1529 Self {
1530 time_series: HashMap::new(),
1531 aggregated_stats: HashMap::new(),
1532 retention_settings: HashMap::new(),
1533 current_data_size: 0,
1534 max_data_size: 1_000_000, }
1536 }
1537
1538 fn add_measurement(&mut self, measurement: MetricMeasurement) {
1539 let metric_type = measurement.metric_type.clone();
1540
1541 let time_series = self
1543 .time_series
1544 .entry(metric_type.clone())
1545 .or_insert_with(VecDeque::new);
1546 time_series.push_back(measurement.clone());
1547
1548 self.update_aggregated_stats(metric_type, &measurement);
1550
1551 self.cleanup_old_data();
1553 }
1554
1555 fn update_aggregated_stats(
1556 &mut self,
1557 metric_type: MetricType,
1558 measurement: &MetricMeasurement,
1559 ) {
1560 let stats = self
1562 .aggregated_stats
1563 .entry(metric_type)
1564 .or_insert_with(|| AggregatedStats {
1565 mean: 0.0,
1566 std_dev: 0.0,
1567 min: f64::INFINITY,
1568 max: f64::NEG_INFINITY,
1569 median: 0.0,
1570 p95: 0.0,
1571 p99: 0.0,
1572 sample_count: 0,
1573 last_updated: SystemTime::now(),
1574 });
1575
1576 if let MetricValue::Float(value) = measurement.value {
1577 stats.sample_count += 1;
1578 stats.min = stats.min.min(value);
1579 stats.max = stats.max.max(value);
1580 stats.last_updated = SystemTime::now();
1581
1582 stats.mean =
1584 (stats.mean * (stats.sample_count - 1) as f64 + value) / stats.sample_count as f64;
1585 }
1586 }
1587
1588 fn cleanup_old_data(&mut self) {
1589 }
1592}
1593
1594impl AnalyticsEngine {
1595 fn new() -> Self {
1596 Self {
1597 trend_analyzers: HashMap::new(),
1598 anomaly_detectors: HashMap::new(),
1599 correlation_analyzers: Vec::new(),
1600 predictive_models: HashMap::new(),
1601 analysis_cache: HashMap::new(),
1602 }
1603 }
1604}
1605
1606impl AlertManager {
1607 fn new(_thresholds: AlertThresholds) -> Self {
1608 Self {
1609 active_alerts: HashMap::new(),
1610 alert_rules: Vec::new(),
1611 alert_handlers: Vec::new(),
1612 alert_history: VecDeque::new(),
1613 suppression_rules: Vec::new(),
1614 }
1615 }
1616}
1617
1618impl OptimizationAdvisor {
1619 fn new() -> Self {
1620 Self {
1621 optimization_strategies: HashMap::new(),
1622 recommendation_engine: RecommendationEngine::new(),
1623 active_recommendations: Vec::new(),
1624 recommendation_history: VecDeque::new(),
1625 }
1626 }
1627}
1628
1629impl RecommendationEngine {
1630 fn new() -> Self {
1631 Self {
1632 ml_models: HashMap::new(),
1633 rule_based_rules: Vec::new(),
1634 knowledge_base: KnowledgeBase::new(),
1635 }
1636 }
1637}
1638
1639impl KnowledgeBase {
1640 fn new() -> Self {
1641 Self {
1642 best_practices: HashMap::new(),
1643 issue_solutions: HashMap::new(),
1644 platform_knowledge: HashMap::new(),
1645 }
1646 }
1647}
1648
1649impl PerformanceDashboard {
1650 fn new() -> Self {
1651 Self {
1652 widgets: HashMap::new(),
1653 layout: DashboardLayout {
1654 layout_type: LayoutType::Grid,
1655 grid_dimensions: (4, 3),
1656 widget_positions: HashMap::new(),
1657 },
1658 update_frequency: Duration::from_secs(1),
1659 dashboard_state: DashboardState {
1660 active_widgets: HashSet::new(),
1661 last_update: SystemTime::now(),
1662 mode: DashboardMode::Monitoring,
1663 },
1664 }
1665 }
1666}
1667
1668impl ExportManager {
1669 fn new(_settings: ExportSettings) -> Self {
1670 Self {
1671 exporters: HashMap::new(),
1672 export_queue: VecDeque::new(),
1673 export_stats: ExportStatistics {
1674 total_exports: 0,
1675 failed_exports: 0,
1676 average_export_time: Duration::from_millis(0),
1677 total_data_volume: 0,
1678 last_export_time: SystemTime::now(),
1679 },
1680 }
1681 }
1682}
1683
1684impl MonitoringStatus {
1685 fn new() -> Self {
1686 Self {
1687 overall_status: SystemStatus::Offline,
1688 platform_statuses: HashMap::new(),
1689 active_collectors: 0,
1690 total_data_points: 0,
1691 active_alerts: 0,
1692 uptime: Duration::from_secs(0),
1693 }
1694 }
1695}
1696
1697impl Default for MonitoringConfig {
1699 fn default() -> Self {
1700 Self {
1701 monitoring_interval: Duration::from_secs(1),
1702 data_retention_period: Duration::from_secs(24 * 3600), alert_thresholds: AlertThresholds::default(),
1704 enabled_metrics: HashSet::new(),
1705 platform_configs: HashMap::new(),
1706 export_settings: ExportSettings::default(),
1707 }
1708 }
1709}
1710
1711impl Default for AlertThresholds {
1712 fn default() -> Self {
1713 Self {
1714 max_gate_error_rate: 0.01,
1715 max_readout_error_rate: 0.05,
1716 min_coherence_time: Duration::from_micros(50),
1717 max_calibration_drift: 0.1,
1718 max_temperature: 300.0, max_queue_depth: 1000,
1720 max_execution_time: Duration::from_secs(300),
1721 }
1722 }
1723}
1724
1725impl Default for ExportSettings {
1726 fn default() -> Self {
1727 Self {
1728 enable_export: false,
1729 export_formats: vec![ExportFormat::JSON],
1730 export_destinations: vec![],
1731 export_frequency: Duration::from_secs(3600), compression_enabled: true,
1733 }
1734 }
1735}
1736
1737impl fmt::Display for MetricType {
1739 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1740 match self {
1741 MetricType::GateErrorRate => write!(f, "Gate Error Rate"),
1742 MetricType::QubitCoherenceTime => write!(f, "Qubit Coherence Time"),
1743 MetricType::SystemUptime => write!(f, "System Uptime"),
1744 MetricType::Custom(name) => write!(f, "Custom: {}", name),
1745 _ => write!(f, "{:?}", self),
1746 }
1747 }
1748}
1749
1750impl fmt::Display for AlertLevel {
1751 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1752 match self {
1753 AlertLevel::Info => write!(f, "INFO"),
1754 AlertLevel::Warning => write!(f, "WARNING"),
1755 AlertLevel::Critical => write!(f, "CRITICAL"),
1756 AlertLevel::Emergency => write!(f, "EMERGENCY"),
1757 }
1758 }
1759}
1760
1761#[cfg(test)]
1762mod tests {
1763 use super::*;
1764
1765 #[test]
1766 fn test_realtime_monitor_creation() {
1767 let config = MonitoringConfig::default();
1768 let monitor = RealtimeMonitor::new(config);
1769 assert!(monitor.is_ok());
1770 }
1771
1772 #[test]
1773 fn test_metric_measurement() {
1774 let measurement = MetricMeasurement {
1775 metric_type: MetricType::GateErrorRate,
1776 value: MetricValue::Float(0.001),
1777 timestamp: SystemTime::now(),
1778 qubit: Some(QubitId::new(0)),
1779 gate_type: Some(NativeGateType::CNOT),
1780 metadata: HashMap::new(),
1781 uncertainty: Some(0.0001),
1782 };
1783
1784 assert_eq!(measurement.metric_type, MetricType::GateErrorRate);
1785 assert!(matches!(measurement.value, MetricValue::Float(0.001)));
1786 }
1787
1788 #[test]
1789 fn test_superconducting_collector() {
1790 let config = PlatformMonitoringConfig {
1791 platform: HardwarePlatform::Superconducting,
1792 monitored_metrics: HashSet::new(),
1793 sampling_rates: HashMap::new(),
1794 custom_thresholds: HashMap::new(),
1795 connection_settings: HashMap::new(),
1796 };
1797
1798 let mut collector = SuperconductingCollector::new(config);
1799 assert_eq!(collector.platform(), HardwarePlatform::Superconducting);
1800 assert!(!collector.is_connected());
1801
1802 assert!(collector.initialize().is_ok());
1803 assert!(collector.is_connected());
1804
1805 let metrics = collector.collect_metrics();
1806 assert!(metrics.is_ok());
1807 assert!(!metrics.unwrap().is_empty());
1808 }
1809
1810 #[test]
1811 fn test_data_store() {
1812 let mut store = RealtimeDataStore::new(Duration::from_secs(3600));
1813
1814 let measurement = MetricMeasurement {
1815 metric_type: MetricType::GateErrorRate,
1816 value: MetricValue::Float(0.001),
1817 timestamp: SystemTime::now(),
1818 qubit: None,
1819 gate_type: None,
1820 metadata: HashMap::new(),
1821 uncertainty: None,
1822 };
1823
1824 store.add_measurement(measurement);
1825
1826 assert!(store.time_series.contains_key(&MetricType::GateErrorRate));
1827 assert!(store
1828 .aggregated_stats
1829 .contains_key(&MetricType::GateErrorRate));
1830
1831 let stats = store
1832 .aggregated_stats
1833 .get(&MetricType::GateErrorRate)
1834 .unwrap();
1835 assert_eq!(stats.sample_count, 1);
1836 assert_eq!(stats.mean, 0.001);
1837 }
1838
1839 #[test]
1840 fn test_alert_creation() {
1841 let alert = Alert {
1842 id: "test_alert".to_string(),
1843 level: AlertLevel::Warning,
1844 message: "Test alert message".to_string(),
1845 affected_metrics: vec![MetricType::GateErrorRate],
1846 timestamp: SystemTime::now(),
1847 source: "test".to_string(),
1848 suggested_actions: vec!["Check calibration".to_string()],
1849 status: AlertStatus::Active,
1850 };
1851
1852 assert_eq!(alert.level, AlertLevel::Warning);
1853 assert_eq!(alert.status, AlertStatus::Active);
1854 assert!(alert.affected_metrics.contains(&MetricType::GateErrorRate));
1855 }
1856
1857 #[test]
1858 fn test_monitoring_config() {
1859 let config = MonitoringConfig::default();
1860 assert_eq!(config.monitoring_interval, Duration::from_secs(1));
1861 assert_eq!(config.data_retention_period, Duration::from_secs(24 * 3600));
1862 assert!(!config.export_settings.enable_export);
1863 }
1864
1865 #[test]
1866 fn test_metric_value_types() {
1867 let float_value = MetricValue::Float(1.23);
1868 let int_value = MetricValue::Integer(42);
1869 let bool_value = MetricValue::Boolean(true);
1870 let duration_value = MetricValue::Duration(Duration::from_millis(100));
1871
1872 assert!(matches!(float_value, MetricValue::Float(1.23)));
1873 assert!(matches!(int_value, MetricValue::Integer(42)));
1874 assert!(matches!(bool_value, MetricValue::Boolean(true)));
1875 assert!(matches!(duration_value, MetricValue::Duration(_)));
1876 }
1877
1878 #[test]
1879 fn test_alert_thresholds() {
1880 let thresholds = AlertThresholds::default();
1881 assert_eq!(thresholds.max_gate_error_rate, 0.01);
1882 assert_eq!(thresholds.max_readout_error_rate, 0.05);
1883 assert_eq!(thresholds.min_coherence_time, Duration::from_micros(50));
1884 }
1885
1886 #[test]
1887 fn test_optimization_recommendation() {
1888 let recommendation = OptimizationRecommendation {
1889 id: "test_rec".to_string(),
1890 recommendation_type: RecommendationType::GateOptimization,
1891 description: "Optimize gate sequence".to_string(),
1892 affected_components: vec!["qubit_0".to_string()],
1893 expected_improvement: ExpectedImprovement {
1894 fidelity_improvement: Some(0.001),
1895 speed_improvement: Some(0.1),
1896 error_rate_reduction: Some(0.0005),
1897 resource_savings: None,
1898 },
1899 implementation_difficulty: DifficultyLevel::Medium,
1900 priority: RecommendationPriority::High,
1901 timestamp: SystemTime::now(),
1902 };
1903
1904 assert_eq!(
1905 recommendation.recommendation_type,
1906 RecommendationType::GateOptimization
1907 );
1908 assert_eq!(
1909 recommendation.implementation_difficulty,
1910 DifficultyLevel::Medium
1911 );
1912 assert_eq!(recommendation.priority, RecommendationPriority::High);
1913 }
1914
1915 #[test]
1916 fn test_export_settings() {
1917 let settings = ExportSettings {
1918 enable_export: true,
1919 export_formats: vec![ExportFormat::JSON, ExportFormat::CSV],
1920 export_destinations: vec![],
1921 export_frequency: Duration::from_secs(1800),
1922 compression_enabled: true,
1923 };
1924
1925 assert!(settings.enable_export);
1926 assert_eq!(settings.export_formats.len(), 2);
1927 assert!(settings.compression_enabled);
1928 }
1929
1930 #[test]
1931 fn test_monitoring_status() {
1932 let status = MonitoringStatus::new();
1933 assert_eq!(status.overall_status, SystemStatus::Offline);
1934 assert_eq!(status.active_collectors, 0);
1935 assert_eq!(status.total_data_points, 0);
1936 }
1937}