Дублирование журналов при вызове logging.basicConfig

#python-3.6 #python-logging

Вопрос:

Проблема: Когда я вызываю logging.basicConfig в дополнение к настройке моего собственного регистратора, я получаю дубликаты журналов

  • Я использую python 3.6.8
  • Простое решение — не вызывать logging.basicConfig-однако я импортирую модули, которые его вызывают
  • Я не понимаю, почему дублируются журналы. Я проверил количество обработчиков в регистраторе, и есть только один обработчик

Код для воспроизведения проблемы

 import logging
import sys

# create a logger, add a handler and a formatter
log = logging.getLogger(__name__)
log.setLevel(logging.INFO)
handler = logging.StreamHandler(stream=sys.stdout)
handler.setFormatter(logging.Formatter("%(levelname)s:%(name)s:%(message)s"))
log.addHandler(handler)

# call basicConfig
logging.basicConfig(level=logging.INFO) # logs not duplicated if this line is removed

# create a log message
log.info("hello world")

# verify the number of handlers on the logger
print(f" num_handlers = {len(log.handlers)}")

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#INFO:__main__:hello world
#INFO:__main__:hello world
#num_handlers = 1
 

Ответ №1:

Регистраторы Python существуют в иерархии. Существует корневой регистратор (доступный с root = logging.getLogger() помощью), который всегда находится в корне/верхней части иерархии и который настраивается при basicConfig вызове. Каждый другой регистратор распространяет свои журналы вверх по иерархии, поэтому каждый журнал в конечном итоге достигнет корневого регистратора (точнее: обработчиков корневых регистраторов).

Одним из возможных решений является прекращение распространения вашего регистратора:

 log = logging.getLogger(__name__)
log.propagate = False