Я использую модуль ведения журнала Python и хочу отключить сообщения журнала, выводимые сторонними модулями, которые я импортирую. Например, я использую что-то вроде следующего:
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)
Он распечатывает мои отладочные сообщения, когда я выполняю logger.debug («мое сообщение!»), Но он также распечатывает отладочные сообщения из любого модуля, который я импортирую (например, запросы и ряд других вещей).
Я хотел бы видеть только сообщения журнала от интересующих меня модулей. Можно ли сделать так, чтобы модуль ведения журнала делал это?
В идеале я хотел бы иметь возможность указывать регистратору, что он должен печатать сообщения из «ModuleX, ModuleY» и игнорировать все остальные.
Я посмотрел на следующее, но я не хочу отключать / включать ведение журнала перед каждым вызовом импортированной функции: ведение журнала - как игнорировать журналы импортированного модуля?
__name__
r, но я все еще вижу журналы импортированных модулей. Я пытаюсь настроить ведение журнала с помощью файла конфигурации ini, что мне для этого делать?__name__
тоже у меня не получилось. Может потому, что я использую автономный скрипт, а не "модуль"? Что сработало для меня, так это настроить ведение журнала для импортированных модулей (matpplotlib
в моем случае) черезlogging.getLogger("matplotlib").setLevel(logging.WARNING)
и для моего скрипта черезlogging.basicConfig
.logger.debug
вместоlogging.debug
». Легко сделать ошибку, используя ведение журнала вместо регистратора, но это узурпирует всю умную конфигурацию, которую вы хотите настроить. Я провел последние пару часов, живя в этом!logger = logging.getLogger('package.my_module')
вызовы и ваши couldlogger.debug/warning
, без настройки уровней ведения журнала или обработчиков. При записи двоичного приложения там вы должны определить уровень для различных журналов и обработчиков. Библиотеки, содержащие конфигурацию журналирования, всегда будут проблемой.logging.info
). Есть ли способ специально отключить корневые журналы из этого пакета?Если вы собираетесь использовать
logging
пакет python , общепринято определять регистратор в каждом модуле, который его использует.Многие популярные пакеты python делают это, в том числе
requests
. Если пакет использует это соглашение, легко включить / отключить ведение журнала для него, потому что имя регистратора будет таким же, как имя пакета (или будет дочерним элементом этого регистратора). Вы даже можете записать его в тот же файл, что и другие ваши регистраторы.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)
источник
logging.basicConfig(...)
все регистраторы теперь будут выводиться либо наlogging.lastResort
(начиная с Python 3.2, который является stderr), если обработчик не был указан, либо на обработчик, который вы установили. Так что не используйте его, иначе вы все равно продолжите получать все сообщения журнала.Не уверен, уместно ли это для публикации, но я застрял на долгое время и хотел помочь кому-нибудь с той же проблемой, так как нигде больше не нашел!
Я получал журналы отладки из matplotlib, несмотря на то, что следовал довольно простой документации в расширенном руководстве по ведению журнала и устранению неполадок . Я запускал свой логгер в
main()
одном файле и импортировал функцию для создания графика из другого файла (куда я импортировал matplotlib).Что сработало для меня, так это установка уровня matplotlib перед его импортом, а не после, как это было для других модулей в моем основном файле. Мне это показалось нелогичным, поэтому, если кто-то знает, как можно настроить конфигурацию для регистратора, который еще не был импортирован, мне было бы любопытно узнать, как это работает. Благодарность!
В моем основном файле:
import logging import requests logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) logging.getLogger('requests').setLevel(logging.DEBUG) def main(): ...
В моем
plot.py
файле:import logging logging.getLogger('matplotlib').setLevel(logging.WARNING) import matplotlib.pyplot as plt def generatePlot(): ...
источник
logger.DEBUG
должно бытьlogging.DEBUG
matplotlib
чтобыWARNING
после того, как я импортировал модуль, так как добавление его перед импортом даст пух-ошибку. У меня все еще работало. Я используюmatplotlib==3.3.2
Python 3.7, если это помогает.@Bakuriu довольно элегантно объясняет функцию. И наоборот, вы можете использовать этот
getLogger()
метод для получения и перенастройки / отключения нежелательных регистраторов.Я также хотел добавить, что
logging.fileConfig()
метод принимает параметр, вызываемый,disable_existing_loggers
который отключит любые ранее определенные средства ведения журнала (т.е. в импортированных модулях).источник
Это отключает все существующие регистраторы, например, созданные импортированными модулями, при этом по-прежнему используется корневой регистратор (и без необходимости загружать внешний файл).
logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': True, })
Обратите внимание, что вам нужно сначала импортировать все модули, которые вы не хотите регистрировать! В противном случае они не будут считаться «существующими регистраторами». Затем он отключит все регистраторы из этих модулей. Это может привести к тому, что вы также упустите важные ошибки!
Более подробные примеры использования связанных параметров для конфигурации см. На https://gist.github.com/st4lk/6287746 , а вот (частично рабочий) пример использования YAML для настройки с
coloredlog
библиотекой.источник
request
например, но не будет работать, когда импортированные модули создают свои регистраторы внутри своего класса, который вы вызовете позже, как этоAPScheduler
происходит при вызовеBackgroundScheduler.BackgroundScheduler()
. См. Здесь решение: stackoverflow.com/a/48891485/2441026Вы можете использовать что-то вроде:
logging.getLogger("imported_module").setLevel(logging.WARNING) logging.getLogger("my_own_logger_name").setLevel(logging.DEBUG)
Это установит уровень журнала моего собственного модуля на DEBUG, не позволяя импортированному модулю использовать тот же уровень.
Примечание:
"imported_module"
можно заменить наimported_module.__name__
(без кавычек), а"my_own_logger_name"
можно заменить на,__name__
если вы предпочитаете это делать.источник
У меня такая же проблема. У меня есть файл logging_config.py, который я импортирую во все другие файлы py. В файле logging_config.py я установил уровень ведения журнала корневого журнала на ERROR (по умолчанию это предупреждение):
logging.basicConfig( handlers=[ RotatingFileHandler('logs.log',maxBytes=1000, backupCount=2), logging.StreamHandler(), #print to console ], level=logging.ERROR )
В других модулях я импортирую logging_config.py, объявляю новый регистратор и устанавливаю его уровень на отладку:
Таким образом, все, что я регистрирую в своих файлах py, регистрируется, но все, что регистрируется на уровне отладки и информации импортированными модулями, такими как urllib, request, boto3 и т. Д., Не регистрируется. Если в этом модуле импорта есть какая-то ошибка, то она регистрируется, поскольку я установил уровень корневых регистраторов на ERROR.
источник
Еще одна вещь, которую следует учитывать, - это свойство распространения класса Logger.
Например, библиотека py-suds для обработки вызовов мыла, даже помещенная в 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)
журналы журналов о модуле sxbasics.py создание огромного количества журналов
что, поскольку распространение журналов по умолчанию True, вместо этого я восстановил 514 МБ журналов.
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)
источник