Cómo configurar todos los registradores en una aplicación

El módulo de registro de Python permite a los módulos o clases definir sus propios registradores. Y diferentes madereros pueden tener diferentes manejadores. Algunos de ellos pueden optar por iniciar sesión en un archivo, mientras que otros optan por iniciar sesión en, por ejemplo, stdout.

Ahora mi aplicación usa varios de estos módulos, cada uno con sus propios registradores que tienen varios manejadores. ¿Puedo unificar el comportamiento de registro para que todos los registros vayan a un archivo de registro que especificé? En otras palabras, ¿hay una manera de .config () todos los manejadores de los registradores a la vez, desde un solo lugar?

Probablemente debería consultar el CÓMO de Python Logging para comprender cómo funciona.

En resumen, todo lo que suelen hacer los módulos es obtener un registrador de la forma G_LOG = logging.getLogger('package.name') y enviar mensajes al registrador: G_LOG.info('some message'), G_LOG.exception('something bad happened') . Los módulos no suelen configurar nada.

La aplicación que utiliza los módulos puede activar el inicio de sesión y configurar los manejadores en función de los nombres del registrador:

  • escuchar todos los mensajes, o
  • escuchar solo mensajes por encima de un cierto umbral, o
  • escuchar los mensajes solo de los registradores cuyo nombre comience con el package , o
  • escuche los mensajes solo de los registradores cuyo nombre comience con package.name , etc.

La forma más sencilla es configurar el registro a través de logging.basicConfig en algún lugar al principio de su aplicación:

 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename=log_file, filemode='a') 

De esa manera, escribirá todos los mensajes de registro de todos los módulos en el log_file .

Si necesita una estrategia de registro más detallada (coloque los registros de diferentes registradores en diferentes archivos o envíe astackmientos a un archivo separado), es mejor definir un archivo de configuración de registro y configurar el registro utilizando logging.config.dictConfig o logging.config.fileConfig .

PS Por lo general creo dos registradores como variables de módulo:

 G_LOG = logging.getLogger(__name__) ST_LOG = logging.getLogger('stacktrace.' + __name__) 

a G_LOG solo envío mensajes de una línea. Para ST_LOG mensajes importantes usando ST_LOG.exception que implícitamente tiene exc_info=True y escribe el seguimiento de stack de la excepción actual.

Al inicio de la aplicación, cargo una configuración que configura dos registradores (y dos controladores de archivos para ellos): uno que recibe mensajes que comienzan con stacktrace y tiene propagate=0 (es decir, los mensajes de stacktrace no son visibles en la parte superior) y root logger que maneja el rest de los mensajes. No pondré aquí mis archivos de configuración de registro completos, ya que es un trabajo de casa útil para entender cómo funciona todo.

Desde el registro HOWTO :

Los registradores secundarios propagan mensajes hasta los controladores asociados con sus registradores de antepasados. Debido a esto, no es necesario definir y configurar los controladores para todos los registradores que utiliza una aplicación. Es suficiente configurar los manejadores para un registrador de nivel superior y crear registradores secundarios según sea necesario. (Sin embargo, puede desactivar la propagación configurando el atributo de propagación de un registrador en Falso).

Cualquier controlador que agregue al registrador raíz se utilizará cuando los registradores secundarios creen entradas de registro.

 import logging root_handler = ... root_logger = logging.getLogger() root_logger.addHandler(root_handler) # Will receive all log entries # Meanwhile in a module... import logging logger = logging.getLogger(__name__) logger.error(...) # Will go to root_handler