From c42a76b3d79476673f21027fdff850b47f2420e2 Mon Sep 17 00:00:00 2001 From: Lars Date: Mon, 12 Jan 2026 09:04:36 +0100 Subject: [PATCH] Add dedicated logging for ID collisions in ingestion_processor.py Implement a new method to log ID collisions into a separate file (logs/id_collisions.log) for manual analysis. This update captures relevant metadata in JSONL format, enhancing traceability during the ingestion process. The logging occurs when a conflict is detected between existing and new files sharing the same note_id, improving error handling and diagnostics. --- app/core/ingestion/ingestion_processor.py | 62 ++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/app/core/ingestion/ingestion_processor.py b/app/core/ingestion/ingestion_processor.py index 525dc73..e657948 100644 --- a/app/core/ingestion/ingestion_processor.py +++ b/app/core/ingestion/ingestion_processor.py @@ -91,6 +91,58 @@ class IngestionService: except Exception as e: logger.warning(f"DB initialization warning: {e}") + def _log_id_collision( + self, + note_id: str, + existing_path: str, + conflicting_path: str, + action: str = "ERROR" + ) -> None: + """ + WP-24c v4.5.10: Loggt ID-Kollisionen in eine dedizierte Log-Datei. + + Schreibt alle ID-Kollisionen in logs/id_collisions.log für manuelle Analyse. + Format: JSONL (eine Kollision pro Zeile) mit allen relevanten Metadaten. + + Args: + note_id: Die doppelte note_id + existing_path: Pfad der bereits vorhandenen Datei + conflicting_path: Pfad der kollidierenden Datei + action: Gewählte Aktion (z.B. "ERROR", "SKIPPED") + """ + import json + from datetime import datetime + + # Erstelle Log-Verzeichnis falls nicht vorhanden + log_dir = "logs" + if not os.path.exists(log_dir): + os.makedirs(log_dir) + + log_file = os.path.join(log_dir, "id_collisions.log") + + # Erstelle Log-Eintrag mit allen relevanten Informationen + log_entry = { + "timestamp": datetime.now().isoformat(), + "note_id": note_id, + "existing_file": { + "path": existing_path, + "filename": os.path.basename(existing_path) if existing_path else None + }, + "conflicting_file": { + "path": conflicting_path, + "filename": os.path.basename(conflicting_path) if conflicting_path else None + }, + "action": action, + "collection_prefix": self.prefix + } + + # Schreibe als JSONL (eine Zeile pro Eintrag) + try: + with open(log_file, "a", encoding="utf-8") as f: + f.write(json.dumps(log_entry, ensure_ascii=False) + "\n") + except Exception as e: + logger.warning(f"⚠️ Konnte ID-Kollision nicht in Log-Datei schreiben: {e}") + def _persist_rejected_edges(self, note_id: str, rejected_edges: List[Dict[str, Any]]) -> None: """ WP-24c v4.5.9: Persistiert abgelehnte Kanten für Audit-Zwecke. @@ -274,11 +326,19 @@ class IngestionService: old_path = old_payload.get("path", "") if old_path and old_path != normalized_file_path: # ID-Kollision erkannt: Zwei verschiedene Dateien haben dieselbe note_id + # Logge die Kollision in dedizierte Log-Datei + self._log_id_collision( + note_id=note_id, + existing_path=old_path, + conflicting_path=normalized_file_path, + action="ERROR" + ) logger.error( f"❌ [ID-KOLLISION] Kritischer Fehler: Die note_id '{note_id}' wird bereits von einer anderen Datei verwendet!\n" f" Bereits vorhanden: '{old_path}'\n" f" Konflikt mit: '{normalized_file_path}'\n" - f" Lösung: Bitte ändern Sie die 'id' im Frontmatter einer der beiden Dateien, um eine eindeutige ID zu gewährleisten." + f" Lösung: Bitte ändern Sie die 'id' im Frontmatter einer der beiden Dateien, um eine eindeutige ID zu gewährleisten.\n" + f" Details wurden in logs/id_collisions.log gespeichert." ) return {**result, "status": "error", "error": "id_collision", "note_id": note_id, "existing_path": old_path, "conflicting_path": normalized_file_path}