use super::config::OperationStats;
use super::{HardwareMetrics, HardwareResult};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{Duration, Instant, SystemTime};
#[derive(Debug, Clone)]
pub struct PerformanceMonitor {
pub history: HashMap<String, Vec<(SystemTime, HardwareMetrics)>>,
pub operation_stats: HashMap<String, OperationStats>,
pub efficiency_scores: HashMap<String, f64>,
pub anomaly_detector: AnomalyDetector,
}
#[derive(Debug, Clone)]
pub struct AnomalyDetector {
pub thresholds: HashMap<String, f64>,
pub anomalies: Vec<Anomaly>,
pub algorithms: Vec<AnomalyAlgorithm>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Anomaly {
pub device_id: String,
pub anomaly_type: AnomalyType,
pub severity: AnomalySeverity,
pub timestamp: SystemTime,
pub score: f64,
pub details: String,
pub affected_metrics: Vec<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AnomalyType {
HighLatency,
LowThroughput,
HighMemoryUsage,
HighTemperature,
HighPowerConsumption,
FrequentErrors,
DeviceUnavailable,
PerformanceDegradation,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AnomalySeverity {
Low,
Medium,
High,
Critical,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AnomalyAlgorithm {
StatisticalOutlier,
MovingAverage,
ExponentialSmoothing,
IsolationForest,
OneClassSVM,
LSTMAutoencoder,
}
#[derive(Debug, Clone)]
pub struct HealthChecker {
pub results: HashMap<String, HealthCheckResult>,
pub schedule: HashMap<String, Duration>,
pub policies: HashMap<String, HealthCheckPolicy>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HealthCheckResult {
pub device_id: String,
pub status: HealthStatus,
pub timestamp: SystemTime,
pub response_time: f64,
pub health_score: f64,
pub issues: Vec<HealthIssue>,
pub recommendations: Vec<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum HealthStatus {
Healthy,
Warning,
Critical,
Unhealthy,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HealthIssue {
pub issue_type: HealthIssueType,
pub severity: AnomalySeverity,
pub description: String,
pub affected_components: Vec<String>,
pub potential_causes: Vec<String>,
pub suggested_fixes: Vec<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum HealthIssueType {
PerformanceDegradation,
MemoryLeak,
HighTemperature,
PowerIssues,
CommunicationErrors,
DriverIssues,
HardwareFaults,
ConfigurationIssues,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HealthCheckPolicy {
pub interval: Duration,
pub timeout: Duration,
pub retry_count: u32,
pub failure_threshold: u32,
pub recovery_threshold: u32,
pub detailed_diagnostics: bool,
}
impl PerformanceMonitor {
pub fn new() -> Self {
Self {
history: HashMap::new(),
operation_stats: HashMap::new(),
efficiency_scores: HashMap::new(),
anomaly_detector: AnomalyDetector::new(),
}
}
pub fn update_metrics(&mut self, device_id: &str, metrics: &HardwareMetrics) {
let entry = self.history.entry(device_id.to_string()).or_default();
entry.push((SystemTime::now(), metrics.clone()));
if entry.len() > 1000 {
entry.drain(..500);
}
self.anomaly_detector.check_anomalies(device_id, metrics);
}
pub fn analyze_performance(&mut self, device_metrics: &HashMap<String, HardwareMetrics>) {
for (device_id, metrics) in device_metrics {
let efficiency = self.calculate_efficiency_score(metrics);
self.efficiency_scores.insert(device_id.clone(), efficiency);
}
}
pub fn calculate_efficiency_score(&self, metrics: &HardwareMetrics) -> f64 {
let utilization_score = (metrics.utilization / 100.0).min(1.0);
let latency_score = (1.0 / (1.0 + metrics.latency / 100.0)).min(1.0);
let throughput_score = (metrics.throughput / 1000.0).min(1.0);
utilization_score * 0.4 + latency_score * 0.3 + throughput_score * 0.3
}
pub fn get_top_performers(&self, count: usize) -> Vec<(String, f64)> {
let mut performers: Vec<_> =
self.efficiency_scores.iter().map(|(id, score)| (id.clone(), *score)).collect();
performers.sort_by(|a, b| b.1.partial_cmp(&a.1).expect("Partial comparison failed"));
performers.truncate(count);
performers
}
}
impl AnomalyDetector {
pub fn new() -> Self {
Self {
thresholds: [
("high_latency".to_string(), 100.0),
("low_throughput".to_string(), 10.0),
("high_temperature".to_string(), 80.0),
("high_power".to_string(), 200.0),
("high_utilization".to_string(), 95.0),
]
.into(),
anomalies: Vec::new(),
algorithms: vec![
AnomalyAlgorithm::StatisticalOutlier,
AnomalyAlgorithm::MovingAverage,
],
}
}
pub fn check_anomalies(&mut self, device_id: &str, metrics: &HardwareMetrics) {
if metrics.latency > *self.thresholds.get("high_latency").unwrap_or(&100.0) {
self.add_anomaly(
device_id,
AnomalyType::HighLatency,
AnomalySeverity::High,
metrics.latency / 100.0,
"Latency exceeds threshold",
);
}
if metrics.throughput < *self.thresholds.get("low_throughput").unwrap_or(&10.0) {
self.add_anomaly(
device_id,
AnomalyType::LowThroughput,
AnomalySeverity::Medium,
1.0 - (metrics.throughput / 100.0),
"Throughput below threshold",
);
}
if let Some(temp) = metrics.temperature {
if temp > *self.thresholds.get("high_temperature").unwrap_or(&80.0) {
self.add_anomaly(
device_id,
AnomalyType::HighTemperature,
AnomalySeverity::Critical,
temp / 100.0,
"Temperature exceeds safe limits",
);
}
}
if metrics.power_consumption > *self.thresholds.get("high_power").unwrap_or(&200.0) {
self.add_anomaly(
device_id,
AnomalyType::HighPowerConsumption,
AnomalySeverity::Medium,
metrics.power_consumption / 300.0,
"Power consumption is high",
);
}
if metrics.utilization > *self.thresholds.get("high_utilization").unwrap_or(&95.0) {
self.add_anomaly(
device_id,
AnomalyType::HighMemoryUsage,
AnomalySeverity::Low,
metrics.utilization / 100.0,
"Utilization is very high",
);
}
if self.anomalies.len() > 1000 {
self.anomalies.drain(..500);
}
}
fn add_anomaly(
&mut self,
device_id: &str,
anomaly_type: AnomalyType,
severity: AnomalySeverity,
score: f64,
details: &str,
) {
let anomaly = Anomaly {
device_id: device_id.to_string(),
anomaly_type,
severity,
timestamp: SystemTime::now(),
score,
details: details.to_string(),
affected_metrics: vec!["latency".to_string(), "throughput".to_string()],
};
self.anomalies.push(anomaly);
}
pub fn get_recent_anomalies(&self, device_id: &str, duration: Duration) -> Vec<&Anomaly> {
let threshold = SystemTime::now() - duration;
self.anomalies
.iter()
.filter(|a| a.device_id == device_id && a.timestamp >= threshold)
.collect()
}
}
impl HealthChecker {
pub fn new() -> Self {
Self {
results: HashMap::new(),
schedule: HashMap::new(),
policies: HashMap::new(),
}
}
pub async fn check_device(&mut self, device_id: &str) -> HardwareResult<()> {
let start_time = Instant::now();
let health_score = 0.95; let issues = vec![];
let result = HealthCheckResult {
device_id: device_id.to_string(),
status: HealthStatus::Healthy,
timestamp: SystemTime::now(),
response_time: start_time.elapsed().as_millis() as f64,
health_score,
issues,
recommendations: vec!["Monitor temperature".to_string()],
};
self.results.insert(device_id.to_string(), result);
Ok(())
}
pub fn get_health_status(&self, device_id: &str) -> Option<HealthStatus> {
self.results.get(device_id).map(|result| result.status)
}
pub fn set_policy(&mut self, device_id: &str, policy: HealthCheckPolicy) {
self.policies.insert(device_id.to_string(), policy);
}
pub fn get_all_results(&self) -> &HashMap<String, HealthCheckResult> {
&self.results
}
}
impl Default for HealthCheckPolicy {
fn default() -> Self {
Self {
interval: Duration::from_secs(60),
timeout: Duration::from_secs(10),
retry_count: 3,
failure_threshold: 3,
recovery_threshold: 2,
detailed_diagnostics: true,
}
}
}
impl Default for PerformanceMonitor {
fn default() -> Self {
Self::new()
}
}
impl Default for AnomalyDetector {
fn default() -> Self {
Self::new()
}
}
impl Default for HealthChecker {
fn default() -> Self {
Self::new()
}
}