KI-Agent / agent /parser.py
Astridkraft's picture
Update agent/parser.py
836a02d verified
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])