#!/usr/bin/env python3 """ Health Report Generator Generates formatted health reports with: - 0-100 overall scores - Component breakdown - Specific issue examples - Actionable recommendations """ import json from datetime import datetime from typing import List, Dict from pathlib import Path class HealthReportGenerator: """Generate formatted health reports.""" def __init__(self): """Initialize report generator.""" pass def generate_dashboard_report(self, health_data: Dict) -> str: """ Generate formatted dashboard report. Args: health_data: Health data from system orchestrator Returns: Formatted dashboard string """ overall = health_data['overall_score'] status = health_data['status'].upper() timestamp = datetime.fromtimestamp(health_data['timestamp']).strftime('%Y-%m-%d %H:%M UTC') report = f""" ╔════════════════════════════════════════════════════════════════════╗ ║ LUZIA SYSTEM HEALTH REPORT ║ ║ {timestamp:42} ║ ╚════════════════════════════════════════════════════════════════════╝ OVERALL HEALTH SCORE: {overall:3.1f}/100 [{self._status_emoji(status)} {status}] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ COMPONENT BREAKDOWN: """ components = health_data.get('component_scores', {}) for name, score in components.items(): emoji = self._score_emoji(score) status_str = 'healthy' if score >= 80 else 'degraded' if score >= 60 else 'critical' report += f" {name:15} {score:6.1f}/100 {emoji} {status_str}\n" report += "\n" + "━" * 70 + "\n\n" return report def generate_component_report(self, component_name: str, component_data: Dict) -> str: """ Generate detailed component report. Args: component_name: Name of component (kg, conductor, etc) component_data: Component health data Returns: Formatted component report """ report = f"\n{'=' * 70}\n" report += f"{component_name.upper()} COMPONENT REPORT\n" report += f"{'=' * 70}\n\n" # Score score = component_data.get('health_score') or component_data.get('overall_score', 0) status = component_data.get('status', 'unknown').upper() report += f"Score: {score:3.1f}/100 [{status}]\n\n" # Issues issues = component_data.get('issues', []) if issues: report += f"ISSUES FOUND ({len(issues)}):\n\n" for i, issue in enumerate(issues[:10], 1): if isinstance(issue, dict): report += f" [{i}] {issue.get('severity', 'UNKNOWN').upper()}\n" report += f" {issue.get('pattern', 'Unknown pattern')}\n" if 'example' in issue: example = issue['example'] if len(example) > 80: example = example[:80] + "..." report += f" Example: {example}\n\n" else: report += f" [{i}] {issue}\n\n" # Recommendations recommendations = component_data.get('recommendations', []) if recommendations: report += f"RECOMMENDATIONS:\n\n" for i, rec in enumerate(recommendations, 1): report += f" {i}. {rec}\n" report += "\n" return report def generate_summary_report(self, health_data: Dict) -> str: """ Generate executive summary report. Args: health_data: Health data from system orchestrator Returns: Summary report string """ overall = health_data['overall_score'] timestamp = datetime.fromtimestamp(health_data['timestamp']).strftime('%Y-%m-%d %H:%M UTC') report = f""" ╔════════════════════════════════════════════════════════════════════╗ ║ SYSTEM HEALTH SUMMARY ║ ║ {timestamp:42} ║ ╚════════════════════════════════════════════════════════════════════╝ OVERALL SCORE: {overall:3.1f}/100 COMPONENT STATUS: """ components = health_data.get('component_scores', {}) for name, score in components.items(): emoji = self._score_emoji(score) report += f" ├─ {name:20} {score:6.1f}/100 {emoji}\n" report += """ NEXT STEPS: """ # Provide actionable next steps based on score if overall >= 80: report += """ ✓ System is healthy - continue normal operations - Run weekly full audits for proactive monitoring - Review error patterns for systemic improvements """ elif overall >= 60: report += f""" ⚠ System is degraded - {int(100 - overall)} points below healthy threshold - Address component issues in order of severity - Run luzia health --full for detailed analysis - Implement recommended fixes for each component """ else: report += """ ✗ System is critical - immediate action required - Run luzia health --full immediately - Address URGENT issues first - Contact administrator if problems persist """ report += f"\nFor detailed analysis:\n luzia health --full\n\n" return report def generate_full_report(self, all_health_data: Dict) -> str: """ Generate comprehensive full system report. Args: all_health_data: Complete health data dict Returns: Full report string """ report = self.generate_dashboard_report(all_health_data) # Add capacity section capacity = all_health_data.get('capacity', {}) report += f""" SYSTEM CAPACITY: Disk Usage: {capacity['disk']['usage_pct']:5.1f}% ({capacity['disk']['status']}) Memory Usage: {capacity['memory']['usage_pct']:5.1f}% ({capacity['memory']['status']}) CPU Load: {capacity['cpu']['load_pct']:5.1f}% ({capacity['cpu']['status']}) Concurrency: {capacity['concurrency']['active_agents']}/{capacity['concurrency']['max_concurrent']} agents """ # Configuration status config = all_health_data.get('configuration', {}) report += f""" CONFIGURATION STATUS: Config File: {'✓' if config['config_file_valid'] else '✗'} Permissions: {'✓' if config['permissions_valid'] else '✗'} Databases: {'✓' if config['databases_accessible'] else '✗'} MCP Servers: {'✓' if config['mcp_servers_configured'] else '✗'} """ # Integration tests integration = all_health_data.get('integration', {}) report += f""" INTEGRATION TESTS: KG Query: {'✓' if integration['kg_query'] else '✗'} Conductor R/W: {'✓' if integration['conductor_rw'] else '✗'} Context Retrieval: {'✓' if integration['context_retrieval'] else '✗'} Bash Execution: {'✓' if integration['bash_execution'] else '✗'} """ # Issues summary all_issues = [] all_issues.extend(capacity.get('issues', [])) all_issues.extend(config.get('issues', [])) all_issues.extend(integration.get('issues', [])) if all_issues: report += f""" ISSUES FOUND ({len(all_issues)}): """ for issue in all_issues[:20]: report += f" • {issue}\n" if len(all_issues) > 20: report += f"\n ... and {len(all_issues) - 20} more issues\n" report += f"\n{'━' * 70}\n" return report def save_report(self, filename: str, content: str) -> Path: """ Save report to file. Args: filename: Filename to save content: Report content Returns: Path to saved file """ output_path = Path('/home/admin') / filename output_path.write_text(content) return output_path def _status_emoji(self, status: str) -> str: """Get emoji for status.""" emojis = { 'HEALTHY': '✅', 'DEGRADED': '⚠️', 'CRITICAL': '❌', 'UNKNOWN': '❓' } return emojis.get(status, '❓') def _score_emoji(self, score: float) -> str: """Get emoji for score.""" if score >= 80: return '✅' elif score >= 60: return '⚠️' else: return '❌' if __name__ == '__main__': generator = HealthReportGenerator() # Example health data sample_data = { 'overall_score': 87, 'status': 'healthy', 'timestamp': 1704729600, 'component_scores': { 'kg': 92, 'conductor': 84, 'context': 89, 'scripts': 95, 'routines': 88, 'capacity': 81, 'configuration': 98, 'integration': 100 }, 'capacity': { 'disk': {'usage_pct': 82, 'status': 'warning'}, 'memory': {'usage_pct': 65, 'status': 'healthy'}, 'cpu': {'load_pct': 45, 'status': 'healthy'}, 'concurrency': {'active_agents': 2, 'max_concurrent': 4}, 'issues': [] }, 'configuration': { 'config_file_valid': True, 'permissions_valid': True, 'databases_accessible': True, 'mcp_servers_configured': True, 'issues': [] }, 'integration': { 'kg_query': True, 'conductor_rw': True, 'context_retrieval': True, 'bash_execution': True, 'issues': [] } } print(generator.generate_dashboard_report(sample_data)) print(generator.generate_summary_report(sample_data))