Files

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 fijo
  • prefijo_árbol: caracteres de indentación y árbol según profundidad
  • mensaje: 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/