Spaces:
Running
Running
| import re | |
| from pathlib import Path | |
| class LogParser: | |
| def __init__(self): | |
| # Bekannte Fehlermuster | |
| self.patterns = { | |
| "import_error": r"ImportError: No module named ['\"]([^'\"]+)['\"]", | |
| "syntax_error": r"SyntaxError: (.+)", | |
| "indentation_error": r"IndentationError: (.+)", | |
| "name_error": r"NameError: name ['\"]([^'\"]+)['\"] is not defined", | |
| "type_error": r"TypeError: (.+)", | |
| "attribute_error": r"AttributeError: (.+)", | |
| "key_error": r"KeyError: ['\"]([^'\"]+)['\"]", | |
| "index_error": r"IndexError: (.+)", | |
| "value_error": r"ValueError: (.+)", | |
| "zero_division": r"ZeroDivisionError: (.+)", | |
| "file_not_found": r"FileNotFoundError: (.+)", | |
| "permission_error": r"PermissionError: (.+)", | |
| "connection_error": r"ConnectionError: (.+)", | |
| "timeout_error": r"TimeoutError: (.+)", | |
| "memory_error": r"MemoryError: (.+)", | |
| "cuda_error": r"CUDA out of memory", | |
| "oom_error": r"OutOfMemoryError|OOM", | |
| "runtime_error": r"RuntimeError: (.+)", | |
| "assertion_error": r"AssertionError: (.+)", | |
| "modulenotfound": r"ModuleNotFoundError: No module named ['\"]([^'\"]+)['\"]" | |
| } | |
| def parse_log_file(self, log_path): | |
| """Liest und parst eine Log-Datei""" | |
| log_path = Path(log_path) | |
| if not log_path.exists(): | |
| return {"error": "Datei nicht gefunden"} | |
| with open(log_path, 'r') as f: | |
| content = f.read() | |
| return self.parse_log_content(content) | |
| def parse_log_content(self, content): | |
| """Extrahiert Fehler aus Log-Text""" | |
| result = { | |
| "errors": [], | |
| "warnings": [], | |
| "traceback": [], | |
| "summary": "" | |
| } | |
| lines = content.split('\n') | |
| in_traceback = False | |
| traceback_lines = [] | |
| for line in lines: | |
| # Traceback erkennen | |
| if "Traceback (most recent call last)" in line: | |
| in_traceback = True | |
| traceback_lines = [line] | |
| continue | |
| if in_traceback: | |
| traceback_lines.append(line) | |
| if line.startswith(" "): | |
| continue | |
| else: | |
| # Fehler gefunden | |
| error_info = self._extract_error(line) | |
| if error_info: | |
| result["errors"].append(error_info) | |
| result["traceback"] = "\n".join(traceback_lines[-10:]) # Letzte 10 Zeilen | |
| in_traceback = False | |
| continue | |
| # Warnungen | |
| if "warning" in line.lower(): | |
| result["warnings"].append(line.strip()) | |
| # Einzelfehler (ohne Traceback) | |
| error_info = self._extract_error(line) | |
| if error_info and not in_traceback: | |
| result["errors"].append(error_info) | |
| # Zusammenfassung erstellen | |
| result["summary"] = self._create_summary(result) | |
| return result | |
| def _extract_error(self, line): | |
| """Extrahiert Fehlertyp und -nachricht""" | |
| for error_type, pattern in self.patterns.items(): | |
| match = re.search(pattern, line, re.IGNORECASE) | |
| if match: | |
| return { | |
| "type": error_type, | |
| "message": match.group(0), | |
| "detail": match.group(1) if match.groups() else "", | |
| "line": line.strip() | |
| } | |
| return None | |
| def _create_summary(self, result): | |
| """Erstellt prägnante Zusammenfassung""" | |
| errors = result["errors"] | |
| if not errors: | |
| return "Keine eindeutigen Fehler gefunden." | |
| main_error = errors[0] | |
| summary = f"❌ {main_error['type']}: {main_error['detail']}" | |
| if len(errors) > 1: | |
| summary += f"\n⚠️ +{len(errors)-1} weitere Fehler" | |
| if result["warnings"]: | |
| summary += f"\n⚠️ {len(result['warnings'])} Warnungen" | |
| return summary | |
| def extract_relevant_context(self, content, max_lines=20): | |
| """Extrahiert relevante Zeilen um Fehler herum""" | |
| lines = content.split('\n') | |
| error_indices = [] | |
| for i, line in enumerate(lines): | |
| if self._extract_error(line): | |
| error_indices.append(i) | |
| if not error_indices: | |
| return content[:500] # Erste 500 Zeichen | |
| # Kontext um ersten Fehler | |
| start = max(0, error_indices[0] - 10) | |
| end = min(len(lines), error_indices[0] + 10) | |
| return "\n".join(lines[start:end]) |