4.4 KiB
Especificación de Logging — ComercioNet
Objetivo
Implementar un sistema de logging jerárquico con formato visual de árbol (├──, └──, │) que permita entender rápidamente el flujo de procesamiento de cada archivo y sus sub-operaciones (SAP B1, SQL, etc.).
API
El módulo logger_manager.py expone una función única:
from logger_manager import get_logger
log = get_logger() # devuelve una instancia de TaskLogger
Métodos de TaskLogger
| Método | Descripción | Prefijo visual |
|---|---|---|
info(msg, _last=False) |
Mensaje informativo | ├── o └── |
warning(msg, _last=False) |
Advertencia | ├── o └── |
error(msg, _last=False) |
Error | ├── o └── |
task(name, emoji="") |
Context manager — abre un bloque anidado (push depth) | ├── + emoji + name |
last_task(name, emoji="") |
Context manager — último bloque del padre (push depth) | └── + emoji + name |
Parámetro _last
En info(), warning(), error(), el parámetro _last=True cambia el prefijo de ├── a └──, indicando que es el último mensaje en ese nivel.
log.info("Primer paso") # ├── Primer paso
log.info("Paso intermedio") # ├── Paso intermedio
log.info("Último paso", _last=True) # └── Último paso
Estructura jerárquica con task() / last_task()
with log.task("📦 Archivo X.xml"):
log.info("XML parseado")
with log.task("🔐 SAP B1"):
log.info("Sesión iniciada")
log.info("Catálogo OK")
log.last_task("📁 Movido a processed")
Salida generada
2026-07-31 10:15:03 ─── 📦 Archivo X.xml
├── XML parseado
├── 🔐 SAP B1
│ ├── Sesión iniciada
│ └── Catálogo OK
└── 📁 Movido a processed
Formato de cada línea
{timestamp} ─── {prefijo_árbol}{mensaje}
Ejemplo:
2026-07-31 10:15:03 ─── │ ├── XML parseado
timestamp:YYYY-MM-DD HH:mm:ss(precisión de segundos)───: separador fijoprefijo_árbol: caracteres de indentación y árbol según profundidadmensaje: texto del log
Formato en archivo de log
El archivo logs/comercio-net.log usa el mismo formato con caracteres de árbol. No se incluyen niveles (INFO, WARNING, ERROR) en el texto — la diferenciación visual se logra con emojis y el contexto jerárquico.
Emojis por etapa
| Etapa | Emoji |
|---|---|
| Procesar archivo XML | 📦 |
| Parseo XML / datos extraídos | 📄 |
| Guardar JSON / HTML | 💾 |
| SAP B1 (sesión, catálogo, draft) | 🔐 |
| Consultas HTTP (GET / POST) | 🔄 |
| Éxito / Draft creado | ✅ |
| Advertencia (precio difiere) | ⚠️ |
| Error | ❌ |
| Archivo movido | 📁 |
| Inicio / fin de servicio | 🚀 / 🛑 |
Configuración vía entorno
Variable LOG_LEVEL en .env (valores: DEBUG, INFO, WARNING, ERROR). Por defecto INFO.
LOG_LEVEL=DEBUG
Thread-safety
Se usa contextvars para mantener el stack de profundidad por cada hilo / contexto asíncrono, permitiendo ejecución concurrente sin mezclar indentaciones.
Archivos modificados
| Archivo | Cambio |
|---|---|
logger_manager.py |
Clases TaskLogger, TreeFormatter, _TaskContext. get_logger() devuelve TaskLogger. |
service.py |
Usa get_logger(). process_file() y bloques SAP envueltos con task(). |
sapb1_manager.py |
Usa log.info()/warning()/error() en lugar de print(). |
sql_manager.py |
Usa log.error() en lugar de print(). |
main.py |
Usa get_logger() y task() en el ciclo principal. |
mail_sender.py |
Usa log.info()/warning() para logging de envío de correos. |
Ejemplo completo de salida
2026-07-31 10:15:03 ─── 🚀 Servicio ComercioNet - Procesador OC
2026-07-31 10:15:03 ─── 📦 OC98765.xml
├── 📄 XML parseado (orden E001-2439)
├── 💾 JSON guardado en data/output/OC98765.json
├── 💾 HTML generado
├── 🔐 SAP B1
│ ├── Sesión iniciada (B1SESSION: a634d0ec...)
│ ├── 🔄 [GET] CardCode por GLN
│ ├── Catálogo: 1520 items
│ ├── Precios: 980 registros
│ ├── ✅ Draft creado → DocEntry 2022
│ └── 💾 Payload guardado
└── 📁 XML movido a processed/