Watch at EaseHistorias. Respuestas. Perspectiva.

Tecnología · GUÍA PRÁCTICA

¿Python registra cada mensaje dos veces? Audita handlers y propagación

Marca un record, sigue cada handler hasta root y separa configuración repetida, defaults del framework y captura multiproceso antes de quitar un solo borde.

Original diagram tracing one LogRecord through child, ancestor and root handlers.
Ilustración original: sigue el record por cada handler antes de cambiar propagation. Watch at Ease

Una línea duplicada aún no es diagnóstico. Un LogRecord puede llegar al handler hijo y al ancestro; una ruta puede añadir handlers al mismo logger; el framework puede poseer otro stream; o procesos y collectors distintos pueden generar eventos parecidos.

La reparación segura etiqueta un registro de prueba, guarda PID, logger e identidad del handler y dibuja la ruta a cada sink. Cambia un solo límite de propiedad y repite el comando original.

Distingue evento de línea duplicada

Emite un token único con PID, logger, nivel y timestamp preciso. Captura consola, archivo y collector por separado. Texto igual puede ser eventos distintos y formatos distintos pueden ser el mismo record.

Repite mediante comando, reloader, launcher o service unit real; python app.py no prueba rutas de uvicorn, gunicorn, cron o contenedor.

Dibuja el grafo logger-handler

Registra name, disabled, effective level, propagate y cada direct handler con object id, clase, nivel, stream/file y formatter; luego recorre parents hasta root.

Si child y ancestor tienen el mismo handler o sink equivalente con propagation, hay dos rutas. Conserva un dueño o detén la propagación en un límite deliberado.

Separa setup repetido de propagación

Compara handler count antes del import, después del startup, tras un request y tras reload. Grafo estable con child/root indica propagation; count creciente indica configuración no idempotente.

Mueve el setup a una sola ruta o reutiliza un handler conocido. No deduzcas duplicación solo por clase.

Respeta dueños de framework y proceso

Inspecciona loggers del framework antes de basicConfig. Uvicorn separa parent, error y access; compara el grafo vivo con documentación actual.

Incluye PID/process name. Workers deben usar QueueHandler hacia un listener o collector; revisa también si stdout y stderr se capturan dos veces.

Quita un borde y valida

Elige un dueño por sink: root, framework branch, queue listener o collector. Quita solo el handler, setup, propagation edge o collector route probado.

Repite startup, request, warning, framework error y access event. Exige un probe por sink, count estable tras reload y conservación de streams requeridos.

Original decision diagram separating ancestor propagation, repeated setup, framework and process duplication.
Ilustración original: cuatro ramas de duplicación requieren reparaciones distintas. Watch at Ease