ProgramaciónDesarrollador backend de Python

¿Cómo funciona el registro en Python a través del módulo logging? ¿Qué niveles de registro existen y cómo configurar correctamente un logger en un proyecto de múltiples módulos? Proporcione ejemplos, explique los matices y errores comunes.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

El módulo logging es la herramienta estándar de Python para llevar registros. Implementa una jerarquía de loggers y soporta niveles de registro (severity levels): DEBUG, INFO, WARNING, ERROR, CRITICAL. Un uso correcto permite gestionar centralizadamente la salida, guardar registros en archivos, enviarlos por correo electrónico, filtrarlos por nivel, etc.

La idea principal es crear loggers con nombres (logging.getLogger(__name__)) en cada módulo, evitando crear un logger raíz global desde cero en cada lugar. La configuración (formato, manejadores, nivel) se realiza centralizadamente al inicio de la aplicación.

Ejemplo de configuración:

import logging logging.basicConfig(format='%(levelname)s:%(name)s:%(message)s', level=logging.INFO) logger = logging.getLogger(__name__) def foo(): logger.info('Mensaje informativo') logger.error('¡Error!') foo()

Pregunta engañosa.

¿Por qué no se puede llamar a logging.basicConfig() en cada módulo? ¿Qué sucederá si se hace esto?

Respuesta: logging.basicConfig() configura el logger raíz solo una vez por sesión de Python. Las llamadas repetidas, si el logger raíz ya ha sido inicializado, serán ignoradas. Como resultado, si diferentes módulos intentan llamar a basicConfig() con sus propios formatos/niveles, ¡solo funcionará el primero!

Ejemplos de errores reales debido al desconocimiento de los matices del tema.


Historia

En un gran proyecto, cada desarrollador configuraba el logging a su gusto a través de basicConfig y manejadores locales. Debido a esto, algunos registros no se mostraban en absoluto, otros se duplicaban 10 veces, y los mensajes de diferentes módulos no cabían en un solo archivo.


Historia

Al migrar un servicio web a un registro jerárquico, olvidaron especificar el nombre del logger a través de getLogger(__name__), escribiendo todo en el logger raíz. Como resultado, no era posible determinar de dónde provenía un registro específico.


Historia

Usaron la función logger.error() para registrar todos los mensajes, incluso los que no eran errores. Como resultado, los sistemas de monitoreo automáticos constantemente "activaban la alarma" porque veían un alto nivel de errores, aunque se trataba simplemente de mensajes de debug/informativos.