Estoy usando el módulo de registro de Python y me gustaría deshabilitar los mensajes de registro impresos por los módulos de terceros que importo. Por ejemplo, estoy usando algo como lo siguiente:
logger = logging.getLogger()
logger.setLevel(level=logging.DEBUG)
fh = logging.StreamHandler()
fh_formatter = logging.Formatter('%(asctime)s %(levelname)s %(lineno)d:%(filename)s(%(process)d) - %(message)s')
fh.setFormatter(fh_formatter)
logger.addHandler(fh)
Esto imprime mis mensajes de depuración cuando hago un logger.debug ("¡mi mensaje!"), Pero también imprime los mensajes de depuración de cualquier módulo que importe (como solicitudes y muchas otras cosas).
Me gustaría ver solo los mensajes de registro de los módulos que me interesan. ¿Es posible hacer que el módulo de registro haga esto?
Idealmente, me gustaría poder decirle al registrador que imprima mensajes de "ModuleX, ModuleY" e ignore todos los demás.
Miré lo siguiente, pero no quiero tener que deshabilitar / habilitar el registro antes de cada llamada a una función importada: registro: ¿cómo ignorar los registros del módulo importado?
__name__
r pero todavía veo los registros de los módulos importados. Estoy intentando configurar el registro con un archivo de configuración ini, ¿qué debo hacer para eso?__name__
tampoco funcionó para mí. ¿Quizás porque estoy usando un script independiente y no un "módulo"? Lo que funcionó para mí fue configurar el registro para módulos importados (matpplotlib
en mi caso) a través delogging.getLogger("matplotlib").setLevel(logging.WARNING)
y para mi script a través delogging.basicConfig
.logger.debug
lugar delogging.debug
". Es un error fácil de cometer al usar el registro en lugar del registrador, pero usurpa toda la configuración inteligente que desea configurar. ¡He pasado las últimas horas viviendo esto!logger = logging.getLogger('package.my_module')
llamadas y sus llamadas couldlogger.debug/warning
, sin configuración de niveles de registro o controladores. Cuando escriba la aplicación binaria allí , debe decidir el nivel de los distintos registros y controladores. Las bibliotecas que contienen la configuración de registro siempre serán un problema.logging.info
). ¿Hay alguna forma de deshabilitar específicamente los registros raíz de este paquete?Si va a usar el
logging
paquete python , es una convención común definir un registrador en cada módulo que lo usa.Muchos paquetes populares de Python hacen esto, incluido
requests
. Si un paquete usa esta convención, es fácil habilitar / deshabilitar el registro para él, porque el nombre del registrador será el mismo nombre que el del paquete (o será un hijo de ese registrador). Incluso puede registrarlo en el mismo archivo que sus otros registradores.logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) requests_logger = logging.getLogger('requests') requests_logger.setLevel(logging.DEBUG) handler = logging.StreamHandler() handler.setLevel(logging.DEBUG) logger.addHandler(handler) requests_logger.addHandler(handler)
fuente
logging.basicConfig(...)
todos los registradores, ahora saldrá alogging.lastResort
(comenzando con Python 3.2, que es stderr) si no se proporcionó un controlador o al controlador que configuró. Así que no lo use o seguirá recibiendo todos los mensajes de registro de todos modos.No estoy seguro de si esto es apropiado para publicar, pero estuve atascado durante mucho tiempo y quería ayudar a cualquiera con el mismo problema, ¡ya que no lo había encontrado en ningún otro lugar!
Obtenía registros de depuración de matplotlib a pesar de seguir la documentación bastante sencilla en el tutorial avanzado de registro y la resolución de problemas . Estaba iniciando mi registrador en
main()
un archivo e importando una función para crear un gráfico desde otro archivo (donde había importado matplotlib).Lo que funcionó para mí fue establecer el nivel de matplotlib antes de importarlo, en lugar de después, como lo hice para otros módulos en mi archivo principal. Esto me pareció contrario a la intuición, por lo que si alguien tiene una idea de cómo puede configurar la configuración para un registrador que aún no se ha importado, tendré curiosidad por saber cómo funciona. ¡Gracias!
En mi archivo principal:
import logging import requests logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) logging.getLogger('requests').setLevel(logging.DEBUG) def main(): ...
En mi
plot.py
archivo:import logging logging.getLogger('matplotlib').setLevel(logging.WARNING) import matplotlib.pyplot as plt def generatePlot(): ...
fuente
logger.DEBUG
debería serlogging.DEBUG
matplotlib
queWARNING
después he importado el módulo, ya que añadir que antes de importar daría una pelusa de errores. Todavía funcionó para mí. Estoy usandomatplotlib==3.3.2
Python 3.7 si ayuda.@Bakuriu explica con bastante elegancia la función. Por el contrario, puede utilizar el
getLogger()
método para recuperar y reconfigurar / deshabilitar los registradores no deseados.También quería agregar que el
logging.fileConfig()
método acepta un parámetro llamadodisable_existing_loggers
que deshabilitará cualquier registrador previamente definido (es decir, en módulos importados).fuente
Esto deshabilita todos los registradores existentes, como los creados por módulos importados, mientras se sigue utilizando el registrador raíz (y sin tener que cargar un archivo externo).
logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': True, })
¡Tenga en cuenta que primero debe importar todos los módulos que no desea que se registren! De lo contrario, no se considerarán "registradores existentes". Luego deshabilitará todos los registradores de esos módulos. ¡Esto podría llevarlo a perderse también errores importantes!
Para obtener ejemplos más detallados sobre el uso de opciones relacionadas para la configuración, consulte https://gist.github.com/st4lk/6287746 , y aquí hay un ejemplo (que funciona parcialmente) usando YAML para la configuración con la
coloredlog
biblioteca.fuente
request
ejemplo, pero no funcionará cuando los módulos importados creen sus registradores dentro de su clase a la que llamarías más tarde, comoAPScheduler
hace cuando llamasBackgroundScheduler.BackgroundScheduler()
. Consulte aquí para obtener una solución: stackoverflow.com/a/48891485/2441026Podrías usar algo como:
logging.getLogger("imported_module").setLevel(logging.WARNING) logging.getLogger("my_own_logger_name").setLevel(logging.DEBUG)
Esto establecerá el nivel de registro de mi propio módulo en DEBUG, mientras que evita que el módulo importado use el mismo nivel.
Nota:
"imported_module"
se puede reemplazar conimported_module.__name__
(sin comillas), y"my_own_logger_name"
se puede reemplazar por__name__
si esa es la forma en que prefiere hacerlo.fuente
Yo tuve el mismo problema. Tengo un archivo logging_config.py que importo en todos los demás archivos py. En el archivo logging_config.py configuré el nivel de registro del registrador raíz en ERROR (de forma predeterminada, su advertencia):
logging.basicConfig( handlers=[ RotatingFileHandler('logs.log',maxBytes=1000, backupCount=2), logging.StreamHandler(), #print to console ], level=logging.ERROR )
En otros módulos, importo logging_config.py y declaro un nuevo registrador y configuro su nivel para depurar:
De esta manera, todo lo que inicie sesión en mis archivos py se registra, pero las cosas que se registran en el nivel de depuración e información mediante módulos importados como urllib, request, boto3, etc.no se registran. Si hay algún error en esos módulos de importación, entonces se registra, ya que configuré el nivel de registradores raíz en ERROR.
fuente
Otra cosa a considerar es la propiedad de propagación de la clase Logger.
Por ejemplo, biblioteca py-suds para manejar llamadas de jabón, incluso poner ERROR
logging.getLogger('suds.client').setLevel(logging.ERROR) logging.getLogger('suds.transport').setLevel(logging.ERROR) logging.getLogger('suds.xsdschema').setLevel(logging.ERROR) logging.getLogger('suds.wsdl').setLevel(logging.ERROR)
registros registros sobre un módulo llamado sxbasics.py creación de una gran cantidad de registros
que debido a que la propagación de los registros es Verdadera de forma predeterminada, estableciendo en Falso, en cambio, recuperé 514 MB de registros.
import logging logging.getLogger("suds").propagate = False logging.getLogger('suds.client').setLevel(logging.ERROR) logging.getLogger('suds.transport').setLevel(logging.ERROR) logging.getLogger('suds.xsdschema').setLevel(logging.ERROR) logging.getLogger('suds.wsdl').setLevel(logging.ERROR)
fuente