"""Text output formatter.""" from typing import Any from loglens.analyzers.analyzer import AnalysisResult from loglens.formatters.base import OutputFormatter from loglens.parsers.base import ParsedLogEntry class TextFormatter(OutputFormatter): """Simple text output formatter.""" def format(self, data: Any) -> str: """Format data as text.""" if isinstance(data, AnalysisResult): return self._format_analysis_result(data) elif isinstance(data, list): return self._format_entries(data) else: return str(data) def _format_analysis_result(self, result: AnalysisResult) -> str: """Format analysis result as text summary.""" lines = [] lines.append("=" * 60) lines.append("LOG ANALYSIS SUMMARY") lines.append("=" * 60) lines.append(f"Total Lines: {result.total_lines}") lines.append(f"Parsed Entries: {result.parsed_count}") lines.append(f"Format Detected: {result.format_detected.value.upper()}") lines.append(f"Analysis Time: {result.analysis_time.isoformat()}") if result.time_range: lines.append(f"Time Range: {result.time_range[0]} to {result.time_range[1]}") lines.append("") lines.append("SEVERITY BREAKDOWN:") lines.append("-" * 40) for level in ["critical", "error", "warning", "info", "debug"]: count = getattr(result, f"{level}_count", 0) lines.append(f" {level.upper():10} : {count}") lines.append("") lines.append("TOP ERROR PATTERNS:") lines.append("-" * 40) for item in result.top_errors[:10]: lines.append(f" {item['pattern']:30} : {item['count']}") if result.suggestions: lines.append("") lines.append("SUGGESTIONS:") lines.append("-" * 40) for i, suggestion in enumerate(result.suggestions, 1): lines.append(f" {i}. {suggestion}") lines.append("=" * 60) return "\n".join(lines) def _format_entries(self, entries: list[ParsedLogEntry]) -> str: """Format log entries as text lines.""" lines = [] for entry in entries: parts = [] if entry.timestamp: parts.append(entry.timestamp.strftime("%Y-%m-%d %H:%M:%S")) severity = (entry.severity or "UNKNOWN").upper() parts.append(f"[{severity:8}]") parts.append(entry.message or entry.raw_line[:100]) if entry.error_pattern: parts.append(f" <{entry.error_pattern}>") lines.append(" ".join(parts)) return "\n".join(lines) def format_entries_compact(self, entries: list[ParsedLogEntry], max_lines: int = 100) -> str: """Format entries compactly.""" lines = [] for entry in entries[:max_lines]: severity = (entry.severity or "?").upper()[0] ts = entry.timestamp.strftime("%H:%M:%S") if entry.timestamp else "??:??:??" message = entry.message or entry.raw_line[:80] lines.append(f"{ts} {severity} {message}") if len(entries) > max_lines: lines.append(f"... and {len(entries) - max_lines} more entries") return "\n".join(lines)