Python logging antes de ejecutar logging.basicConfig?

Parece que si invoca logging.info () ANTES de ejecutar logging.basicConfig, la llamada logging.basicConfig no tendrá ningún efecto. De hecho, no se produce registro.

¿Dónde se documenta este comportamiento? Realmente no entiendo

Puede eliminar los controladores predeterminados y reconfigurar el registro de esta manera:

# if someone tried to log something before basicConfig is called, Python creates a default handler that # goes to the console and will ignore further basicConfig calls. Remove the handler if there is one. root = logging.getLogger() if root.handlers: for handler in root.handlers: root.removeHandler(handler) logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG) 

Sí.

Has pedido que se registre algo. El registro debe, por lo tanto, fabricar una configuración por defecto. Una vez que se configura el registro … bueno … está configurado.

“Con el objeto de registrador configurado, los siguientes métodos crean mensajes de registro:”

Además, puede leer sobre la creación de controladores para evitar el registro falso. Pero eso es más un truco para una mala implementación que una técnica útil.

Hay un truco para esto.

  1. Ningún módulo puede hacer nada excepto las solicitudes de logging.getlogger() a nivel global.

  2. Solo el if __name__ == "__main__": puede hacer una configuración de registro.

Si realiza el registro a nivel global en un módulo, entonces puede forzar el registro para fabricar su configuración predeterminada.

No hagas logging.info globalmente en ningún módulo. Si cree absolutamente que debe tener logging.info a nivel global en un módulo, debe configurar el registro antes de realizar importaciones. Esto lleva a guiones de aspecto desagradable.

En principio, esta respuesta de Carlos A. Ibarra es correcta, sin embargo, la implementación podría fallar, ya que se está repitiendo en una lista que se puede cambiar llamando a removeHandler (). Esto no es seguro. Dos alternativas son:

 while len(logging.root.handlers) > 0: logging.root.removeHandler(logging.root.handlers[-1]) logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG) 

o:

 logging.root.handlers = [] logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG) 

donde el primero de estos dos que usan el bucle es el más seguro (ya que cualquier código de destrucción para el manejador puede llamarse explícitamente dentro del marco de registro). Aún así, esto es un hack, ya que confiamos en logging.root.handlers para ser una lista.

Aquí está la pieza del rompecabezas que las respuestas anteriores no mencionaron … y entonces todo tendrá sentido: el registrador “raíz”, que se usa si llama, por ejemplo, logging.info () antes de iniciar sesión. basicConfig (level = logging.DEBUG): tiene un nivel de registro predeterminado de ADVERTENCIA .

Es por eso que logging.info () y logging.debug () no hacen nada: porque los has configurado para que no lo hagan, por … um … sin configurarlos.

Posiblemente relacionado (este me mordió): cuando NO llamaba a basicConfig, no parecía estar recibiendo mis mensajes de depuración, a pesar de que puse mis controladores a nivel DEBUG. Después de tirar un poco el pelo, descubrí que también tiene que configurar el nivel del registrador personalizado para que sea DEBUG. Si su registrador está configurado en ADVERTENCIA, entonces configurar un controlador en DEBUG (por sí mismo) no le dará ningún resultado en logger.info () y logger.debug ().