trustformers_debug/utilities/
health.rs1use crate::{DebugConfig, DebugSession, QuickDebugLevel, SimplifiedDebugResult};
4use anyhow::Result;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Serialize, Deserialize)]
9pub struct HealthCheckResult {
10 pub overall_score: f64,
11 pub status: String,
12 pub issues: Vec<String>,
13 pub critical_issues: bool,
14 pub timestamp: chrono::DateTime<chrono::Utc>,
15}
16
17#[derive(Debug, Serialize, Deserialize)]
19pub struct DebugSummary {
20 pub config_hash: String,
21 pub total_debug_runs: usize,
22 pub total_issues: usize,
23 pub critical_issues: usize,
24 pub recommendations: Vec<String>,
25 pub timestamp: chrono::DateTime<chrono::Utc>,
26}
27
28#[derive(Debug, Clone)]
30pub enum ExportFormat {
31 Json,
32 Csv,
33 Html,
34}
35
36#[derive(Debug, Clone)]
38pub enum DebugTemplate {
39 Development,
40 Production,
41 Training,
42 Research,
43}
44
45pub struct HealthChecker;
47
48impl HealthChecker {
49 pub async fn quick_health_check<T>(model: &T) -> Result<HealthCheckResult> {
51 let result = crate::quick_debug(model, QuickDebugLevel::Light).await?;
52
53 let health_score = match &result {
54 SimplifiedDebugResult::Light(health) => health.score,
55 SimplifiedDebugResult::Standard { health, .. } => health.score,
56 SimplifiedDebugResult::Deep(report) => {
57 let summary = report.summary();
58 100.0 - (summary.critical_issues as f64 * 20.0 + summary.total_issues as f64 * 5.0)
59 },
60 SimplifiedDebugResult::Production(anomaly) => {
61 100.0 - (anomaly.anomaly_count as f64 * 10.0)
62 },
63 };
64
65 Ok(HealthCheckResult {
66 overall_score: health_score,
67 status: Self::score_to_status(health_score),
68 issues: result.recommendations(),
69 critical_issues: result.has_critical_issues(),
70 timestamp: chrono::Utc::now(),
71 })
72 }
73
74 pub fn score_to_status(score: f64) -> String {
76 match score {
77 s if s >= 90.0 => "Excellent".to_string(),
78 s if s >= 75.0 => "Good".to_string(),
79 s if s >= 50.0 => "Fair".to_string(),
80 s if s >= 25.0 => "Poor".to_string(),
81 _ => "Critical".to_string(),
82 }
83 }
84
85 pub fn generate_debug_summary(
87 config: &DebugConfig,
88 results: &[SimplifiedDebugResult],
89 ) -> DebugSummary {
90 let mut total_issues = 0;
91 let mut critical_issues = 0;
92 let mut all_recommendations = Vec::new();
93
94 for result in results {
95 match result {
96 SimplifiedDebugResult::Light(health) => {
97 if health.score < 50.0 {
98 critical_issues += 1;
99 }
100 total_issues += 1;
101 },
102 SimplifiedDebugResult::Standard { health, .. } => {
103 if health.score < 50.0 {
104 critical_issues += 1;
105 }
106 total_issues += 1;
107 },
108 SimplifiedDebugResult::Deep(report) => {
109 let summary = report.summary();
110 total_issues += summary.total_issues;
111 critical_issues += summary.critical_issues;
112 },
113 SimplifiedDebugResult::Production(anomaly) => {
114 total_issues += anomaly.anomaly_count;
115 if anomaly.severity_level.to_lowercase().contains("critical")
116 || anomaly.severity_level.to_lowercase().contains("high")
117 {
118 critical_issues += 1;
119 }
120 },
121 }
122
123 all_recommendations.extend(result.recommendations());
124 }
125
126 all_recommendations.dedup();
127
128 DebugSummary {
129 config_hash: Self::hash_config(config),
130 total_debug_runs: results.len(),
131 total_issues,
132 critical_issues,
133 recommendations: all_recommendations,
134 timestamp: chrono::Utc::now(),
135 }
136 }
137
138 pub async fn export_debug_data(
140 session: &DebugSession,
141 format: ExportFormat,
142 output_path: &str,
143 ) -> Result<String> {
144 let report = session.generate_snapshot().await?;
145
146 match format {
147 ExportFormat::Json => {
148 let json_data = serde_json::to_string_pretty(&report)?;
149 tokio::fs::write(output_path, json_data).await?;
150 },
151 ExportFormat::Csv => {
152 let csv_data = Self::report_to_csv(&report)?;
153 tokio::fs::write(output_path, csv_data).await?;
154 },
155 ExportFormat::Html => {
156 let html_data = Self::report_to_html(&report)?;
157 tokio::fs::write(output_path, html_data).await?;
158 },
159 }
160
161 Ok(format!("Debug data exported to {}", output_path))
162 }
163
164 pub fn create_debug_template(template_type: DebugTemplate) -> DebugConfig {
166 match template_type {
167 DebugTemplate::Development => DebugConfig {
168 enable_tensor_inspection: true,
169 enable_gradient_debugging: true,
170 enable_model_diagnostics: true,
171 enable_visualization: true,
172 enable_memory_profiling: true,
173 enable_computation_graph_analysis: true,
174 max_tracked_tensors: 1000,
175 max_gradient_history: 100,
176 sampling_rate: 1.0,
177 ..Default::default()
178 },
179 DebugTemplate::Production => DebugConfig {
180 enable_tensor_inspection: false,
181 enable_gradient_debugging: false,
182 enable_model_diagnostics: false,
183 enable_visualization: false,
184 enable_memory_profiling: true,
185 enable_computation_graph_analysis: false,
186 max_tracked_tensors: 10,
187 max_gradient_history: 10,
188 sampling_rate: 0.1,
189 ..Default::default()
190 },
191 DebugTemplate::Training => DebugConfig {
192 enable_tensor_inspection: true,
193 enable_gradient_debugging: true,
194 enable_model_diagnostics: true,
195 enable_visualization: false,
196 enable_memory_profiling: true,
197 enable_computation_graph_analysis: true,
198 max_tracked_tensors: 500,
199 max_gradient_history: 50,
200 sampling_rate: 0.5,
201 ..Default::default()
202 },
203 DebugTemplate::Research => DebugConfig {
204 enable_tensor_inspection: true,
205 enable_gradient_debugging: true,
206 enable_model_diagnostics: true,
207 enable_visualization: true,
208 enable_memory_profiling: true,
209 enable_computation_graph_analysis: true,
210 max_tracked_tensors: 2000,
211 max_gradient_history: 200,
212 sampling_rate: 1.0,
213 ..Default::default()
214 },
215 }
216 }
217
218 fn hash_config(config: &DebugConfig) -> String {
220 use std::collections::hash_map::DefaultHasher;
221 use std::hash::{Hash, Hasher};
222
223 let mut hasher = DefaultHasher::new();
224 format!("{:?}", config).hash(&mut hasher);
225 format!("{:x}", hasher.finish())
226 }
227
228 fn report_to_csv(_report: &crate::DebugReport) -> Result<String> {
230 Ok(format!(
232 "timestamp,score,issues\n{},{},{}",
233 chrono::Utc::now().to_rfc3339(),
234 0, 0 ))
237 }
238
239 fn report_to_html(report: &crate::DebugReport) -> Result<String> {
241 Ok(format!(
243 r#"
244<!DOCTYPE html>
245<html>
246<head>
247 <title>Debug Report</title>
248 <style>
249 body {{ font-family: Arial, sans-serif; margin: 40px; }}
250 .report {{ background: #f5f5f5; padding: 20px; border-radius: 5px; }}
251 </style>
252</head>
253<body>
254 <h1>TrustformeRS Debug Report</h1>
255 <div class="report">
256 <pre>{}</pre>
257 </div>
258</body>
259</html>
260 "#,
261 serde_json::to_string_pretty(report)?
262 ))
263 }
264}