Files
luzia/lib/health_report_generator.py
admin ec33ac1936 Refactor cockpit to use DockerTmuxController pattern
Based on claude-code-tools TmuxCLIController, this refactor:

- Added DockerTmuxController class for robust tmux session management
- Implements send_keys() with configurable delay_enter
- Implements capture_pane() for output retrieval
- Implements wait_for_prompt() for pattern-based completion detection
- Implements wait_for_idle() for content-hash-based idle detection
- Implements wait_for_shell_prompt() for shell prompt detection

Also includes workflow improvements:
- Pre-task git snapshot before agent execution
- Post-task commit protocol in agent guidelines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 10:42:16 -03:00

314 lines
10 KiB
Python

#!/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))