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

В чем смысл setLevel в обработчике каротажа python?

Скажем, у меня есть следующий код:

import logging
import logging.handlers

a = logging.getLogger('myapp')
h = logging.handlers.RotatingFileHandler('foo.log')
h.setLevel(logging.DEBUG)
a.addHandler(h)

# The effective log level is still logging.WARN
print a.getEffectiveLevel() 
a.debug('foo message')
a.warn('warning message')

Я ожидаю, что установка logging.DEBUG на обработчике заставит сообщения отладочного уровня быть записаны в файл журнала. Тем не менее, это печатает 30 для эффективного уровня (равный logging.WARNING, по умолчанию) и только регистрирует сообщение warn в файле журнала, а не отладочное сообщение.

Похоже, что уровень журнала обработчика падает на пол, например. он молча игнорируется. Что заставляет меня задаться вопросом, почему вообще есть setLevel на обработчике?

4b9b3361

Ответ 1

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

import logging
import logging.handlers

a = logging.getLogger('myapp')
a.setLevel(logging.DEBUG)   # set root level
h = logging.handlers.RotatingFileHandler('foo.log')
h.setLevel(logging.DEBUG)
a.addHandler(h)
print a.getEffectiveLevel() 
a.debug('foo message')
a.warn('warning message')

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

import logging
import logging.handlers

a = logging.getLogger('myapp')
a.setLevel(logging.DEBUG)   # set root level

h = logging.handlers.RotatingFileHandler('foo.log')
h.setLevel(logging.DEBUG)
a.addHandler(h)

h2 = logging.handlers.RotatingFileHandler('foo2.log')
h2.setLevel(logging.WARNING)
a.addHandler(h2)

print a.getEffectiveLevel() 
a.debug('foo message')
a.warn('warning message')

Теперь файл журнала foo.log будет содержать оба сообщения, а файл foo2.log будет содержать только предупреждающее сообщение. Вам может быть интересно иметь файл журнала только сообщений об ошибках, а затем просто добавить Handler и установить его уровень на logging.ERROR, используя все те же Logger.

Вы можете думать о уровне ведения журнала Logger в качестве глобального ограничения на то, что сообщения "интересны" для данного регистратора и его обработчиков. После этого сообщения, которые затем регистрируются регистратором, отправляются обработчикам, которые выполняют собственный процесс фильтрации и регистрации.

Ответ 2

В протоколе Python существует два разных понятия: уровень, на который регистрируется журнал регистрации, и уровень, на который фактически активируется обработчик.

Когда выполняется вызов журнала, то, что в основном происходит, является:

if self.level <= loglevel:
    for handler in self.handlers:
        handler(loglevel, message)

Пока каждый из этих обработчиков вызовет:

if self.level <= loglevel:
    # do something spiffy with the log!

Если вы хотите продемонстрировать это в реальном мире, вы можете посмотреть настройки настроек Django. Здесь я укажу соответствующий код.

LOGGING = {
    #snip
    'handlers': {
        'null': {
            'level': 'DEBUG',
            'class': 'logging.NullHandler',
        },
        'console':{
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'filters': ['special']
        }
    },
    'loggers': {
        #snip
        'myproject.custom': {
            # notice how there are two handlers here!
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
            'filters': ['special']
        }
    }
}

Итак, в приведенной выше конфигурации только журналы с getLogger('myproject.custom').info и выше будут обработаны для ведения журнала. Когда это произойдет, консоль выведет все результаты (она выведет все, потому что она установлена ​​на уровень DEBUG), а журнал mail_admins будет выполняться для всех ERROR s, FATAL и CRITICAL с.

Я полагаю, что некоторый код, который не является Django, тоже может помочь:

import logging.handlers as hand
import logging as logging

# to make things easier, we'll name all of the logs by the levels
fatal = logging.getLogger('fatal')
warning = logging.getLogger('warning')
info = logging.getLogger('info')

fatal.setLevel(logging.FATAL)
warning.setLevel(logging.WARNING)
info.setLevel(logging.INFO)    

fileHandler = hand.RotatingFileHandler('rotating.log')

# notice all three are re-using the same handler.
fatal.addHandler(fileHandler)
warning.addHandler(fileHandler)
info.addHandler(fileHandler)

# the handler should log everything except logging.NOTSET
fileHandler.setLevel(logging.DEBUG)

for logger in [fatal,warning,info]:
    for level in ['debug','info','warning','error','fatal']:
        method = getattr(logger,level)
        method("Debug " + logger.name + " = " + level)

# now, the handler will only do anything for *fatal* messages...
fileHandler.setLevel(logging.FATAL)

for logger in [fatal,warning,info]:
    for level in ['debug','info','warning','error','fatal']:
        method = getattr(logger,level)
        method("Fatal " + logger.name + " = " + level)

Это приводит к:

Debug fatal = fatal
Debug warning = warning
Debug warning = error
Debug warning = fatal
Debug info = info
Debug info = warning
Debug info = error
Debug info = fatal
Fatal fatal = fatal
Fatal warning = fatal
Fatal info = fatal

Снова обратите внимание, как info записал что-то в info, warning, ERROR и FATAL, когда обработчик журнала был установлен в DEBUG, но когда обработчик был установлен в FATAL внезапно только сообщения FATAL внесли его в файл.

Ответ 3

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

Подробнее о том, как обрабатываются события регистрации, см. эту диаграмму:

введите описание изображения здесь