Sistema de Logging Centralizado
Arquitectura
SherlockDocs (logger raíz)
├── handlers: FileHandler, StreamHandler, DatabaseHandler
└── hijos (heredan handlers automáticamente):
├── SherlockDocs.sherlock_docs.application.use_cases.process_document
├── SherlockDocs.sherlock_docs.infrastructure.dedup.hybrid_detector
└── ... (cualquier módulo usando get_logger(__name__))
Configuración Inicial (app.py)
from sherlock_docs.infrastructure.logging import setup_logger
logger = setup_logger(
name="SherlockDocs",
log_dir="logs",
db_path="data/database/sherlock.db",
)
Uso en Módulos (OBLIGATORIO)
# ✅ CORRECTO
from sherlock_docs.infrastructure.logging import get_logger
logger = get_logger(__name__) # Hereda handlers del logger raíz
# ❌ INCORRECTO — logs no aparecerán
import logging
logger = logging.getLogger(__name__)
| Método |
Logger creado |
¿Hereda handlers? |
get_logger(__name__) |
SherlockDocs.sherlock_docs.modulo |
✅ Sí |
logging.getLogger(__name__) |
sherlock_docs.modulo |
❌ No |
Qué loguear por componente
| Componente |
Qué loguear |
Nivel |
| OCR adapters |
Inicio, éxito, error con exc_info |
INFO/ERROR |
| NER adapters |
Extracción inicio/fin, errores |
INFO/ERROR |
| Duplicate detection |
Candidatos encontrados, tiempos |
INFO/DEBUG |
| Repository ops |
Save, update, delete |
INFO |
| Pipeline use case |
Cada etapa inicio/fin |
INFO |
| GUI pages |
Errores capturados |
WARNING/ERROR |
Patrón obligatorio
from sherlock_docs.infrastructure.logging import get_logger
logger = get_logger(__name__)
class SomeAdapter:
def process(self, file_path: Path) -> Result:
logger.debug(f"Iniciando: {file_path}")
try:
# ... lógica ...
logger.info(f"Completado: tiempo={processing_time:.0f}ms")
return result
except Exception as e:
logger.error(f"Falló: {e}", exc_info=True)
return Failure(error)
Nunca usar except: pass silencioso. Siempre logger.error(msg, exc_info=True).
Ubicación
- Archivo:
logs/sherlock_YYYY-MM-DD.log (rotación diaria, 30 días)
- Base de datos:
data/database/sherlock.db tabla logs