Модуль Python Logging: пользовательские регистраторы - PullRequest
8 голосов
/ 16 февраля 2012

Я пытался создать пользовательский атрибут для ведения журнала (имя класса вызывающего, имя модуля и т. Д.) И застрял со странным исключением, говорящим мне, что созданный в процессе экземпляр LogRecord не имеет необходимых атрибутов. После небольшого тестирования я получил следующее:

import logging

class MyLogger(logging.getLoggerClass()):
    value = None

logging.setLoggerClass(MyLogger)

loggers = [
    logging.getLogger(),
    logging.getLogger(""),
    logging.getLogger("Name")
]

for logger in loggers:
    print(isinstance(logger, MyLogger), hasattr(logger, "value"))

Этот, казалось бы, правильный фрагмент кода дает:

False False
False False
True True

Ошибка или функция?

Ответы [ 2 ]

6 голосов
/ 16 февраля 2012

Глядя на исходный код, мы видим следующее:

root = RootLogger(WARNING)
def getLogger(name=None):
    if name:
        return Logger.manager.getLogger(name)
    else:
        return root

То есть корневой логгер создается по умолчанию при импорте модуля. Следовательно, каждый раз, когда вы ищите корневой лозер (передав ложное значение, такое как пустая строка), вы будете получать объект logging.RootLogger независимо от любого вызова logging.setLoggerClass.

Что касается используемого класса логгера, мы можем видеть:

_loggerClass = None
def setLoggerClass(klass):
    ...
    _loggerClass = klass

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

В дополнение к этому, глядя на logging.Manager (используется logging.getLogger), мы можем видеть это:

def getLogger(self, name):
    ...
            rv = (self.loggerClass or _loggerClass)(name)

То есть, если self.loggerClass не установлено (чего не будет, если вы не установили его явно), используется класс из глобальной переменной.

Следовательно, это особенность. Корневой регистратор всегда является объектом logging.RootLogger, а другие объекты регистратора создаются на основе конфигурации на тот момент.

2 голосов
/ 16 февраля 2012

logging.getLogger() и logging.getLogger("") не возвращают MyLogger, потому что они возвращают корневой регистратор иерархии журналирования, как описано в документации :

logging.getLogger ([имя])

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

Таким образом, поскольку у вас настроен регистратор:

>>> logging.getLogger()
<logging.RootLogger object at 0x7d9450>
>>> logging.getLogger("foo")
<test3.MyLogger object at 0x76d9f0>

Я не думаю, что это связано с ошибкой KeyEr, с которой вы начали свой пост.Вы должны опубликовать код, который вызвал это исключение (test.py).

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