Mountain/IPC/Common/
HealthStatus.rs

1//! # Health Status Monitoring
2//!
3//! Provides health monitoring and scoring for IPC components.
4//! Used to track the overall health of the IPC system.
5
6use std::{collections::HashSet, time::Instant};
7
8use serde::{Deserialize, Serialize};
9
10/// Severity levels for health issues
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
12pub enum SeverityLevel {
13	/// Informational, no action needed
14	Low,
15	/// Monitor closely, may need attention
16	Medium,
17	/// Requires investigation and action
18	High,
19	/// Immediate attention required
20	Critical,
21}
22
23/// Types of health issues that can be detected
24#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
25pub enum HealthIssue {
26	/// Response time exceeds threshold
27	HighLatency(String),
28	/// High memory usage detected
29	MemoryPressure(String),
30	/// IPC connection failure
31	ConnectionLoss(String),
32	/// Message queue capacity exceeded
33	QueueOverflow(String),
34	/// Unauthorized access or suspicious activity
35	SecurityViolation(String),
36	/// General performance decline
37	PerformanceDegradation(String),
38	/// Custom health issue
39	Custom(String),
40}
41
42impl HealthIssue {
43	/// Get the severity level for this health issue
44	pub fn severity(&self) -> SeverityLevel {
45		match self {
46			HealthIssue::HighLatency(_) => SeverityLevel::Medium,
47			HealthIssue::MemoryPressure(_) => SeverityLevel::Medium,
48			HealthIssue::ConnectionLoss(_) => SeverityLevel::High,
49			HealthIssue::QueueOverflow(_) => SeverityLevel::High,
50			HealthIssue::SecurityViolation(_) => SeverityLevel::Critical,
51			HealthIssue::PerformanceDegradation(_) => SeverityLevel::Medium,
52			HealthIssue::Custom(_) => SeverityLevel::Low,
53		}
54	}
55
56	/// Get the description of this health issue
57	pub fn description(&self) -> &str {
58		match self {
59			HealthIssue::HighLatency(desc) => desc,
60			HealthIssue::MemoryPressure(desc) => desc,
61			HealthIssue::ConnectionLoss(desc) => desc,
62			HealthIssue::QueueOverflow(desc) => desc,
63			HealthIssue::SecurityViolation(desc) => desc,
64			HealthIssue::PerformanceDegradation(desc) => desc,
65			HealthIssue::Custom(desc) => desc,
66		}
67	}
68}
69
70/// Health monitoring state
71#[derive(Debug, Clone, Serialize)]
72pub struct HealthMonitor {
73	/// Overall health score (0-100, where 100 is perfect health)
74	pub health_score:u8,
75	/// Detected health issues
76	pub issues:Vec<(HealthIssue, SeverityLevel)>,
77	/// Number of recovery attempts made
78	pub recovery_attempts:u32,
79	/// Timestamp of last health check (skipped for serialization as Instant is not serializable)
80	#[serde(skip)]
81	pub last_check:Instant,
82}
83
84impl Default for HealthMonitor {
85	fn default() -> Self {
86		Self {
87			health_score:100,
88			issues:Vec::new(),
89			recovery_attempts:0,
90			last_check:Instant::now(),
91		}
92	}
93}
94
95impl HealthMonitor {
96	/// Create a new health monitor with perfect health
97	pub fn new() -> Self {
98		Self {
99			health_score:100,
100			issues:Vec::new(),
101			recovery_attempts:0,
102			last_check:Instant::now(),
103		}
104	}
105
106	/// Add a health issue and update the health score
107	pub fn add_issue(&mut self, issue:HealthIssue) {
108		let severity = issue.severity();
109		self.issues.push((issue.clone(), severity));
110		self.recalculate_score();
111	}
112
113	/// Remove a health issue and update the health score
114	pub fn remove_issue(&mut self, issue:&HealthIssue) {
115		self.issues.retain(|(i, _)| i != issue);
116		self.recalculate_score();
117	}
118
119	/// Clear all health issues and reset to perfect health
120	pub fn clear_issues(&mut self) {
121		self.issues.clear();
122		self.health_score = 100;
123		self.last_check = Instant::now();
124	}
125
126	/// Recalculate health score based on current issues
127	fn recalculate_score(&mut self) {
128		let mut score:i32 = 100;
129
130		for (_issue, severity) in &self.issues {
131			let penalty = match severity {
132				SeverityLevel::Low => 5,
133				SeverityLevel::Medium => 15,
134				SeverityLevel::High => 25,
135				SeverityLevel::Critical => 40,
136			};
137			score -= penalty;
138		}
139
140		self.health_score = score.max(0).min(100) as u8;
141		self.last_check = Instant::now();
142	}
143
144	/// Check if the system is healthy (score >= 70)
145	pub fn is_healthy(&self) -> bool { self.health_score >= 70 }
146
147	/// Check if the system is in critical state (score < 50)
148	pub fn is_critical(&self) -> bool { self.health_score < 50 }
149
150	/// Get issues by severity level
151	pub fn issues_by_severity(&self, severity:SeverityLevel) -> Vec<&HealthIssue> {
152		self.issues.iter().filter(|(_, s)| *s == severity).map(|(i, _)| i).collect()
153	}
154
155	/// Increment recovery attempt counter
156	pub fn increment_recovery_attempts(&mut self) { self.recovery_attempts += 1; }
157}
158