Подтвердить что ты не робот

Регистрация Python перед запуском logging.basicConfig?

Похоже, что если вы вызываете logging.info() ПЕРЕД, вы запустите logging.basicConfig, вызов logging.basicConfig не имеет никакого эффекта. Фактически, никаких протоколов не происходит.

Где такое поведение задокументировано? Я действительно не понимаю.

4b9b3361

Ответ 1

Вы можете удалить обработчики по умолчанию и переконфигурировать ведение журнала следующим образом:

# if someone tried to log something before basicConfig is called, Python creates a default handler that
# goes to the console and will ignore further basicConfig calls. Remove the handler if there is one.
root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG)

Ответ 2

Да.

Вы попросили что-то записать. Таким образом, ведение журнала должно производить конфигурацию по умолчанию. Как только регистрация настроена... ну... она настроена.

"Если сконфигурирован объект журнала, следующие методы создают журнал сообщения:"

Кроме того, вы можете прочитать о создании обработчиков для предотвращения ложных протоколирования. Но это скорее взлом для плохой реализации, чем полезный метод.

Там есть трюк.

  • Ни один модуль не может ничего делать, кроме logging.getlogger() запросов на глобальном уровне.

  • Только if __name__ == "__main__": может выполнять конфигурацию ведения журнала.

Если вы выполняете протоколирование на глобальном уровне в модуле, вы можете принудительно выполнить регистрацию для его конфигурации по умолчанию.

Не выполняйте logging.info глобально в любом модуле. Если вы абсолютно уверены, что у вас должен быть logging.info на глобальном уровне в модуле, вам необходимо настроить ведение журнала перед импортом. Это приводит к неприятным сценариям.

Ответ 3

Этот ответ от Карлоса А. Ибарры в принципе прав, однако реализация может нарушиться, так как вы повторяете список, который можно изменить, вызвав removeHandler(). Это небезопасно. Существуют две альтернативы:

while len(logging.root.handlers) > 0:
    logging.root.removeHandler(logging.root.handlers[-1])
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG)

или

logging.root.handlers = []
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG)

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

Ответ 4

Здесь один кусочек головоломки, о котором упоминалось выше, не упоминается... и тогда все будет иметь смысл: "root" logger - который используется, если вы вызываете, скажем, logging.info() до logging.basicConfig(level = logging.DEBUG) - имеет уровень ведения журнала по умолчанию WARNING.

Вот почему logging.info() и logging.debug() ничего не делают: поскольку вы настроили их не на,...... не настраивая их.

Возможно, связанный (этот бит мне): когда НЕ вызывал basicConfig, я, похоже, не получал отладочные сообщения, хотя я установил обработчики на уровень DEBUG. После немного вытягивания волос я обнаружил, что вы должны установить уровень пользовательского регистратора как DEBUG. Если ваш регистратор настроен на ПРЕДУПРЕЖДЕНИЕ, то установка обработчика на DEBUG (сама по себе) не приведет к выходу на logger.info() и logger.debug().