Вход в Python перед запуском logging.basicConfig? - PullRequest
43 голосов
/ 22 декабря 2009

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

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

Ответы [ 4 ]

45 голосов
/ 07 апреля 2010

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

# 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)
10 голосов
/ 22 декабря 2009

Да.

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

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

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

В этом есть хитрость.

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

  2. Только if __name__ == "__main__": может выполнить настройку регистрации.

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

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

8 голосов
/ 30 января 2013

Этот ответ от Карлоса А. Ибарры в принципе прав, однако реализация может нарушиться, так как вы перебираете список, который можно изменить, вызвав 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, чтобы быть списком.

5 голосов
/ 23 сентября 2012

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...