Mountain/IPC/Common/
HealthStatus.rs1use std::time::Instant;
7
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
12pub enum SeverityLevel {
13 Low,
15 Medium,
17 High,
19 Critical,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
25pub enum HealthIssue {
26 HighLatency(String),
28 MemoryPressure(String),
30 ConnectionLoss(String),
32 QueueOverflow(String),
34 SecurityViolation(String),
36 PerformanceDegradation(String),
38 Custom(String),
40}
41
42impl HealthIssue {
43 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 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#[derive(Debug, Clone, Serialize)]
72pub struct HealthMonitor {
73 pub health_score:u8,
75 pub issues:Vec<(HealthIssue, SeverityLevel)>,
77 pub recovery_attempts:u32,
79 #[serde(skip)]
82 pub last_check:Instant,
83}
84
85impl Default for HealthMonitor {
86 fn default() -> Self {
87 Self {
88 health_score:100,
89 issues:Vec::new(),
90 recovery_attempts:0,
91 last_check:Instant::now(),
92 }
93 }
94}
95
96impl HealthMonitor {
97 pub fn new() -> Self {
99 Self {
100 health_score:100,
101 issues:Vec::new(),
102 recovery_attempts:0,
103 last_check:Instant::now(),
104 }
105 }
106
107 pub fn add_issue(&mut self, issue:HealthIssue) {
109 let severity = issue.severity();
110 self.issues.push((issue.clone(), severity));
111 self.recalculate_score();
112 }
113
114 pub fn remove_issue(&mut self, issue:&HealthIssue) {
116 self.issues.retain(|(i, _)| i != issue);
117 self.recalculate_score();
118 }
119
120 pub fn clear_issues(&mut self) {
122 self.issues.clear();
123 self.health_score = 100;
124 self.last_check = Instant::now();
125 }
126
127 fn recalculate_score(&mut self) {
129 let mut score:i32 = 100;
130
131 for (_issue, severity) in &self.issues {
132 let penalty = match severity {
133 SeverityLevel::Low => 5,
134 SeverityLevel::Medium => 15,
135 SeverityLevel::High => 25,
136 SeverityLevel::Critical => 40,
137 };
138 score -= penalty;
139 }
140
141 self.health_score = score.max(0).min(100) as u8;
142 self.last_check = Instant::now();
143 }
144
145 pub fn is_healthy(&self) -> bool { self.health_score >= 70 }
147
148 pub fn is_critical(&self) -> bool { self.health_score < 50 }
150
151 pub fn issues_by_severity(&self, severity:SeverityLevel) -> Vec<&HealthIssue> {
153 self.issues.iter().filter(|(_, s)| *s == severity).map(|(i, _)| i).collect()
154 }
155
156 pub fn increment_recovery_attempts(&mut self) { self.recovery_attempts += 1; }
158}