Registro para programa multi-módulo.
Quiero agregar un mecanismo de registro a mi programa. La estructura básica del directorio de mi proyecto es así:
.
├── README.md
└── src
├── cli.py
├── module1.py
├── module2.py
└── module3.py
cli.py
importa todos los demás module[1-3].py
, pero, también utilizo todos los demás módulos como ejecutables independientes por sí mismos (incluso fuera del contexto de este proyecto). Es decir, utilizo todos estos comandos:
$ python3 cli.py <args>
$ python3 module1.py
$ python3 module2.py <args>
La estructura básica de los archivos:
import logging
from rich.logging import RichHandler
import module1
formatter = logging.Formatter('[%(asctime)s] %(levelname)s %(message)s')
file_handler = logging.FileHandler('cli.log')
file_handler.setFormatter(formatter)
console_handler = RichHandler()
log = logging.getLogger() # manejador raíz
log.addHandler(file_handler)
log.addHandler(console_handler)
if __name__ == '__main__':
log.error('Hola desde cli.py')
module1.foo()
import logging
log = logging.getLogger(__name__)
formatter = logging.Formatter('[%(asctime)s] %(levelname)s %(message)s')
file_handler = logging.FileHandler('module1.log')
file_handler.setFormatter(formatter)
log.addHandler(file_handler)
def foo():
log.error('Hola desde module1.py')
if __name__ == '__main__':
foo()
Resultados de ejecución:
$ python3 cli.py
[12/14/21 11:29:05] ERROR Hola desde cli.py
ERROR Hola desde module1.py
$ python3 module1.py
Hola desde module1.py
Me pregunto cómo puedo configurar el registro para que incluso cuando ejecute $ python3 module1.py
, tenga el mismo formato definido en el módulo raíz (RichHandler
).
Cuando intenté establecer un formato adicional dentro de module1.py
, resultó en un manejador duplicado.
Entonces básicamente quiero lograr este comportamiento:
shell
$ python3 cli.py
[12/14/21 11:29:05] ERROR Hola desde cli.py # también registrado en cli.log
ERROR Hola desde module1.py # también registrado en cli.log y module1.log
$ python3 module1.py
[12/14/21 11:29:05] ERROR Hola desde module1.py # también registrado en module1.log
davy.ai
Para lograr el comportamiento deseado, podemos modificar la configuración de registro en
module1.py
para heredar los registradores y controladores del registrador raíz definido encli.py
.Primero, necesitamos importar el registrador raíz en
module1.py
agregando la siguiente línea:Luego, podemos eliminar las definiciones del controlador de archivo y del formateador, ya que ya están definidas en el registrador raíz, y cambiar el nivel de registro para que coincida con el definido en el registrador raíz:
Con estos cambios,
module1.py
heredará los controladores y formateadores del registrador raíz definido encli.py
, y registrará mensajes con el mismo formato sin importar cómo se ejecute (como parte decli.py
o como un script independiente).Cabe mencionar que también necesitamos establecer el nivel de registro en
module1.py
para que coincida con el definido en el registrador raíz, ya que el nivel de registro predeterminado esWARNING
.