auth_framework/monitoring/
health.rs1use super::{HealthCheckResult, HealthStatus};
4use serde::{Deserialize, Serialize};
5use std::time::{SystemTime, UNIX_EPOCH};
6use tracing::warn;
7
8pub struct HealthChecker;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct HealthCheckConfig {
14 pub enabled: bool,
16 pub timeout_seconds: u64,
18 pub check_interval_seconds: u64,
20}
21
22impl Default for HealthCheckConfig {
23 fn default() -> Self {
24 Self {
25 enabled: true,
26 timeout_seconds: 30,
27 check_interval_seconds: 60,
28 }
29 }
30}
31
32impl Default for HealthChecker {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl HealthChecker {
39 pub fn new() -> Self {
41 Self
42 }
43
44 pub async fn check_all_components(
46 &self,
47 ) -> std::collections::HashMap<String, HealthCheckResult> {
48 let mut results = std::collections::HashMap::new();
50
51 results.insert("authentication".to_string(), self.check_auth_system().await);
53
54 results.insert("sessions".to_string(), self.check_session_system().await);
56
57 results.insert("tokens".to_string(), self.check_token_system().await);
59
60 results.insert("storage".to_string(), self.check_storage_system().await);
62
63 results.insert("mfa".to_string(), self.check_mfa_system().await);
65
66 results
67 }
68
69 async fn check_auth_system(&self) -> HealthCheckResult {
71 let start_time = SystemTime::now();
72
73 let status = match self.test_auth_system().await {
75 Ok(()) => HealthStatus::Healthy,
76 Err(e) => {
77 warn!("Authentication system health check failed: {}", e);
78 HealthStatus::Critical
79 }
80 };
81
82 let message = match status {
83 HealthStatus::Healthy => "Authentication system operational".to_string(),
84 HealthStatus::Critical => "Authentication system has critical issues".to_string(),
85 _ => "Authentication system status unknown".to_string(),
86 };
87
88 HealthCheckResult {
89 component: "authentication".to_string(),
90 status,
91 message,
92 timestamp: current_timestamp(),
93 response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
94 }
95 }
96
97 async fn test_auth_system(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
99 use sha2::{Digest, Sha256};
100
101 let mut hasher = Sha256::new();
104 hasher.update(b"auth-framework-health-probe");
105 let digest = hasher.finalize();
106
107 if digest.len() != 32 {
109 return Err("SHA-256 produced unexpected digest length".into());
110 }
111
112 Ok(())
113 }
114
115 async fn check_session_system(&self) -> HealthCheckResult {
117 let start_time = SystemTime::now();
118
119 let status = HealthStatus::Healthy;
120 let message = "Session management operational".to_string();
121
122 HealthCheckResult {
123 component: "sessions".to_string(),
124 status,
125 message,
126 timestamp: current_timestamp(),
127 response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
128 }
129 }
130
131 async fn check_token_system(&self) -> HealthCheckResult {
133 let start_time = SystemTime::now();
134
135 let status = HealthStatus::Healthy;
136 let message = "Token management operational".to_string();
137
138 HealthCheckResult {
139 component: "tokens".to_string(),
140 status,
141 message,
142 timestamp: current_timestamp(),
143 response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
144 }
145 }
146
147 async fn check_storage_system(&self) -> HealthCheckResult {
149 let start_time = SystemTime::now();
150
151 let status = HealthStatus::Healthy;
152 let message = "Storage system operational".to_string();
153
154 HealthCheckResult {
155 component: "storage".to_string(),
156 status,
157 message,
158 timestamp: current_timestamp(),
159 response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
160 }
161 }
162
163 async fn check_mfa_system(&self) -> HealthCheckResult {
165 let start_time = SystemTime::now();
166
167 let status = HealthStatus::Healthy;
168 let message = "MFA system operational".to_string();
169
170 HealthCheckResult {
171 component: "mfa".to_string(),
172 status,
173 message,
174 timestamp: current_timestamp(),
175 response_time: start_time.elapsed().unwrap_or_default().as_millis() as u64,
176 }
177 }
178}
179
180fn current_timestamp() -> u64 {
182 SystemTime::now()
183 .duration_since(UNIX_EPOCH)
184 .unwrap_or_default()
185 .as_secs()
186}