2016-02-10 4 views
12

Я использую модуль протоколирования Python и хотел бы отключить сообщения журнала, напечатанные сторонними модулями, которые я импортирую. Например, я использую нечто вроде следующего: («! Мое ​​сообщение»)Python Logging - отключить ведение журнала из импортированных модулей

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 и игнорировать все остальные.

Я посмотрел на следующем, но я не хочу, чтобы отключить/включить ведение журнала перед каждым вызовом к импортируемой функции: logging - how to ignore imported module logs?

ответ

14

Проблема в том, что вызов getLogger без аргументов возвращает корня logger, поэтому, когда вы устанавливаете уровень на logging.DEBUG, вы также устанавливаете уровень для других модулей, которые используют этот регистратор.

Вы можете решить это простым не с использованием корневого регистратора. Для этого просто передать имя в качестве аргумента, например имя вашего модуля:

logger = logging.getLogger('my_module_name') 
# as before 

это создаст новый регистратор и, таким образом, это обыкновение непреднамеренно изменить уровень протоколирования для других модулей.


Очевидно, что вы должны использовать logger.debug вместо logging.debug, поскольку последняя является удобной функцией, которая вызывает debug метода корневого регистратора.

Это указано в Advanced Logging Tutorial. Он также позволяет вам узнать, какой модуль вызвал сообщение журнала простым способом.

4

@Bakuriu довольно элегантно объясняет функцию. И наоборот, вы можете использовать метод getLogger() для извлечения и перенастройки/отключения нежелательных журналов.

Я также хотел бы добавить метод logging.fileConfig() принимает параметр с именем disable_existing_loggers, который отключит любые ранее установленные регистраторы (т. Е. В импортированных модулях).

7

Если вы собираетесь использовать пакет python logging, это обычное соглашение для определения регистратора в каждом модуле, который его использует.

logger = logging.getLogger(__name__) 

Многие популярные пакеты питона сделать это, в том числе 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) 
+0

Помните, что при попытке настроить регистраторы, как в официальном базовом учебнике, с помощью 'logging.basicConfig (...)' все регистраторы теперь будут либо выводиться на 'logging.lastResort' (начиная с Python 3.2, который stderr), если обработчик не был указан или обработчик, который вы установили. Поэтому не используйте его, иначе вы все равно будете получать все сообщения журнала. – user136036

0

Это отключает все существующие регистраторы, такие как созданные импортированными модулями, при этом все еще используется корневой журнал (и без необходимости загрузки внешнего файла).

logging.config.dictConfig({ 
    'version': 1, 
    'disable_existing_loggers': True, 
}) 

Обратите внимание, что вам нужно импортировать все модули, которые вы не хотите, регистрируемые первый! В противном случае они не будут считаться «существующими регистраторами». Затем он отключит все регистраторы из этих модулей. Это может привести к тому, что вы также упустите важные ошибки!

Для получения более подробных примеров с использованием соответствующих параметров конфигурации см. https://gist.github.com/st4lk/6287746, а here - пример (частично работающий) с использованием YAML для конфигурации с библиотекой coloredlog.

+0

Каков ваш вопрос? – user1767754

+0

Это работает, например, для 'request', но это не сработает, когда импортированные модули создадут свои регистраторы внутри своего класса, который вы вызовете позже, например,' APScheduler', когда вы вызываете 'BackgroundScheduler.BackgroundScheduler()'. См. Здесь для решения: https://stackoverflow.com/a/48891485/2441026 – user136036

Смежные вопросы