16.6. logging – Средство журналирования для Python
Исходный код: Lib/logging/__init__.py
Этот модуль определяет функции и классы, реализующие гибкую систему журналирования событий для приложений и библиотек.
Ключевое преимущество наличия API журналирования в модуле стандартной библиотеки заключается в том, что все модули Python могут участвовать в журналировании, поэтому журнал вашего приложения может включать ваши собственные сообщения, объединенные с сообщениями от сторонних модулей.
Модуль предоставляет множество функций и гибкости. Если вы не знакомы с журналированием, лучший способ разобраться – изучить учебные пособия (см. ссылки справа).
Основные классы, определенные модулем, вместе с их функциями, перечислены ниже.
Регистраторы предоставляют интерфейс, который напрямую используется кодом приложения.
Обработчики отправляют записи журнала (созданные регистраторами) в соответствующее место назначения.
Фильтры предоставляют более детальное средство для определения того, какие записи журнала выводить.
Форматировщики определяют макет записей журнала в окончательном выводе.
16.6.1. Объекты Logger
Объекты Logger обладают следующими атрибутами и методами. Обратите внимание, что Logger'ы никогда не создаются напрямую, а всегда через функцию уровня модуля logging.getLogger(name). Многократные вызовы getLogger() с одним и тем же именем всегда возвращают ссылку на один и тот же объект Logger.
Значение name потенциально может быть иерархическим значением, разделённым точками, например foo.bar.baz (хотя это может быть и просто foo). Логгеры, расположенные ниже в иерархическом списке, являются дочерними по отношению к логгерам выше. Например, для логгера с именем foo логгеры с именами foo.bar, foo.bar.baz и foo.bam являются потомками foo. Иерархия имён логгеров аналогична иерархии пакетов Python и идентична ей, если вы организуете свои логгеры на основе модулей, используя рекомендуемую конструкцию logging.getLogger(__name__). Это потому, что в модуле __name__ – это имя модуля в пространстве имён пакетов Python.
-
class
logging.Logger¶ -
propagate¶ Если этот атрибут имеет значение true, события, записанные в этот логгер, будут передаваться обработчикам логгеров более высокого уровня (предков) в дополнение к любым обработчикам, прикреплённым к этому логгеру. Сообщения передаются напрямую обработчикам логгеров-предков – при этом ни уровень, ни фильтры этих логгеров-предков не учитываются.
Если это значение false, сообщения журнала не передаются обработчикам логгеров-предков.
Конструктор устанавливает этот атрибут в
True.Примечание
Если вы прикрепите обработчик к логгеру и к одному или нескольким его предкам, одна и та же запись может быть выдана несколько раз. В общем случае вам не следует прикреплять обработчик более чем к одному логгеру: если вы просто прикрепите его к подходящему логгеру, который находится наиболее высоко в иерархии логгеров, то он будет видеть все события, записанные всеми логгерами-потомками, при условии что их настройка propagate оставлена равной
True. Типичный сценарий – прикреплять обработчики только к корневому логгеру и позволить распространению позаботиться обо всём остальном.
-
setLevel(level)¶ Устанавливает порог для этого логгера в level. Сообщения журнала, которые менее серьёзны, чем level, будут игнорироваться; сообщения журнала, имеющие серьёзность level или выше, будут выданы тем обработчиком (или обработчиками), который обслуживает этот логгер, если только уровень обработчика не был установлен на более высокий уровень серьёзности, чем level.
При создании логгера уровень устанавливается в
NOTSET(что приводит к обработке всех сообщений, если логгер является корневым, или к делегированию родителю, если логгер не является корневым). Обратите внимание, что корневой логгер создаётся с уровнемWARNING.Термин «делегирование родителю» означает, что если логгер имеет уровень NOTSET, то его цепочка логгеров-предков просматривается до тех пор, пока не будет найден предок с уровнем, отличным от NOTSET, или не будет достигнут корень.
Если найден предок с уровнем, отличным от NOTSET, то уровень этого предка считается эффективным уровнем логгера, с которого начался поиск предка, и используется для определения того, как обрабатывать событие журнала.
Если достигнут корень и он имеет уровень NOTSET, то все сообщения будут обработаны. В противном случае уровень корня будет использоваться как эффективный уровень.
Список уровней приведён в разделе Logging Levels.
Изменено в версии 3.2: Параметр level теперь принимает строковое представление уровня, такое как 'INFO', в качестве альтернативы целочисленным константам, например
INFO. Однако обратите внимание, что уровни внутри хранятся как целые числа, и методы, такие какgetEffectiveLevel()иisEnabledFor(), будут возвращать/ожидать передачи целых чисел.
-
isEnabledFor(lvl)¶ Показывает, будет ли сообщение с уровнем важности lvl обработано этим регистратором. Этот метод сначала проверяет уровень, заданный на уровне модуля с помощью
logging.disable(lvl), а затем эффективный уровень регистратора, определяемый функциейgetEffectiveLevel().
-
getEffectiveLevel()¶ Указывает эффективный уровень для данного логгера. Если значение, отличное от
NOTSET, было установлено с помощьюsetLevel(), оно и возвращается. В противном случае иерархия обходится в направлении корневого логгера, пока не будет найдено значение, отличное отNOTSET, и возвращается это значение. Возвращаемое значение является целым числом, обычно одним изlogging.DEBUG,logging.INFOи т.д.
-
getChild(suffix)¶ Возвращает логгер, который является потомком данного логгера, определяемым по суффиксу. Таким образом,
logging.getLogger('abc').getChild('def.ghi')вернёт тот же логгер, который был бы возвращён вызовомlogging.getLogger('abc.def.ghi'). Это удобный метод, полезный, когда родительский логгер именуется, например, через__name__, а не с помощью строкового литерала.Новое в версии 3.2.
-
debug(msg, *args, **kwargs)¶ Регистрирует сообщение с уровнем
DEBUGв данном логгере. msg – это строка формата сообщения, а args – аргументы, которые объединяются с msg с помощью оператора форматирования строк. (Обратите внимание: это означает, что в строке формата можно использовать ключевые слова вместе с одним аргументом-словарём.)В kwargs проверяются три ключевых аргумента: exc_info, stack_info и extra.
Если exc_info не является ложным, это приводит к добавлению информации об исключении в сообщение журнала. Если предоставлен кортеж исключения (в формате, возвращаемом
sys.exc_info()) или экземпляр исключения, используется он; в противном случае вызываетсяsys.exc_info()для получения информации об исключении.Второй необязательный именованный аргумент – stack_info, по умолчанию
False. Если true, в сообщение журнала добавляется информация о стеке, включая сам вызов журналирования. Обратите внимание, что это не та же информация о стеке, что отображается при указании exc_info: первая – это фреймы стека от дна стека до вызова журналирования в текущем потоке, тогда как вторая – это информация о фреймах стека, которые были развёрнуты после исключения, при поиске обработчиков исключений.Можно указать stack_info независимо от exc_info, например, чтобы просто показать, как был достигнут определённый участок кода, даже если никаких исключений не возникало. Фреймы стека выводятся после строки заголовка, которая гласит:
textStack (most recent call last):Это имитирует
Traceback (most recent call last):, который используется при отображении фреймов исключений.Третий ключевой аргумент – extra, который можно использовать для передачи словаря. Этот словарь используется для заполнения __dict__ объекта LogRecord, созданного для события логирования, пользовательскими атрибутами. Затем эти настраиваемые атрибуты можно использовать по своему усмотрению. Например, их можно включать в записываемые сообщения. Например:
pythonFORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s' logging.basicConfig(format=FORMAT) d = {'clientip': '192.168.0.1', 'user': 'fbloggs'} logger = logging.getLogger('tcpserver') logger.warning('Protocol problem: %s', 'connection reset', extra=d)выведет что-то вроде
text2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection resetКлючи в словаре, передаваемом в extra, не должны совпадать с ключами, используемыми системой логирования. (См. документацию
Formatterдля получения дополнительной информации о том, какие ключи используются системой логирования.)При использовании этих атрибутов в сообщениях необходимо соблюдать осторожность. В приведённом выше примере, например,
Formatterнастроен со строкой форматирования, которая ожидает атрибуты 'clientip' и 'user' в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет зарегистрировано, так как возникнет исключение форматирования строки. Поэтому в данном случае необходимо всегда передавать словарь extra с этими ключами.Хотя это может раздражать, данная возможность предназначена для использования в специализированных ситуациях, например, на многопоточных серверах, где один и тот же код выполняется во множестве контекстов, и возникающие интересные условия зависят от этого контекста (такие как IP-адрес удалённого клиента и имя аутентифицированного пользователя в приведённом выше примере). В таких обстоятельствах, скорее всего, будут использоваться специализированные
Formatterс определённымиHandler.Новое в версии 3.2: Добавлен параметр stack_info.
Изменено в версии 3.5: Параметр exc_info теперь может принимать экземпляры исключений.
-
info(msg, *args, **kwargs)¶ Записывает сообщение с уровнем
INFOв этот логгер. Аргументы интерпретируются так же, как дляdebug().
-
warning(msg, *args, **kwargs)¶ Записывает сообщение с уровнем
WARNINGв этот логгер. Аргументы интерпретируются так же, как дляdebug().Примечание
Существует устаревший метод
warn, который функционально идентиченwarning. Посколькуwarnустарел, пожалуйста, не используйте его – используйте вместо негоwarning.
-
error(msg, *args, **kwargs)¶ Записывает сообщение с уровнем
ERRORв этот логгер. Аргументы интерпретируются так же, как дляdebug().
-
critical(msg, *args, **kwargs)¶ Записывает сообщение с уровнем
CRITICALв этот логгер. Аргументы интерпретируются так же, как дляdebug().
-
log(lvl, msg, *args, **kwargs)¶ Регистрирует сообщение с целочисленным уровнем lvl в этом регистраторе. Остальные аргументы интерпретируются так же, как для
debug().
-
exception(msg, *args, **kwargs)¶ Записывает сообщение с уровнем
ERRORв этот логгер. Аргументы интерпретируются так же, как дляdebug(). Информация об исключении добавляется в сообщение. Этот метод следует вызывать только из обработчика исключений.
-
addFilter(filter)¶ Добавляет указанный фильтр filter в этот логгер.
-
removeFilter(filter)¶ Удаляет указанный фильтр filter из этого логгера.
-
filter(record)¶ Применяет фильтры этого регистратора к записи и возвращает true, если запись должна быть обработана. Фильтры опрашиваются по очереди, пока один из них не вернёт false. Если ни один не вернёт false, запись будет обработана (передана обработчикам). Если какой-либо возвращает false, дальнейшая обработка записи не производится.
-
addHandler(hdlr)¶ Добавляет указанный обработчик hdlr в этот логгер.
-
removeHandler(hdlr)¶ Удаляет указанный обработчик hdlr из этого логгера.
-
findCaller(stack_info=False)¶ Находит имя исходного файла и номер строки вызывающего кода. Возвращает имя файла, номер строки, имя функции и информацию о стеке в виде кортежа из 4 элементов. Информация о стеке возвращается как
None, если только stack_info не равноTrue.
-
handle(record)¶ Обрабатывает запись, передавая её всем обработчикам, связанным с этим логгером и его родителями (пока не встретится ложное значение propagate). Этот метод используется для распакованных записей, полученных через сокет, а также для созданных локально. Фильтрация на уровне логгера применяется с помощью
filter().
-
makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)¶ Это фабричный метод, который можно переопределить в подклассах для создания специализированных экземпляров
LogRecord.
-
hasHandlers()¶ Проверяет, настроены ли у этого логгера какие-либо обработчики. Для этого производится поиск обработчиков в этом логгере и его родителях в иерархии логгеров. Возвращает
True, если обработчик найден, иначеFalse. Метод прекращает поиск вверх по иерархии, как только будет найден логгер, у которого атрибут 'propagate' установлен в false – это будет последний логгер, проверяемый на наличие обработчиков.Новое в версии 3.2.
Изменено в версии 3.7: Теперь логгеры можно сериализовать и десериализовать.
-
16.6.2. Уровни журналирования
Числовые значения уровней логирования приведены в следующей таблице. Они нужны в первую очередь, если вы хотите определить собственные уровни и задать им определённые значения относительно предопределённых. Если определить уровень с тем же числовым значением, он перезапишет предопределённое значение; предопределённое имя будет потеряно.
Уровень |
Числовое значение |
|---|---|
|
50 |
|
40 |
|
30 |
|
20 |
|
10 |
|
0 |
16.6.3. Объекты Handler
Обработчики имеют следующие атрибуты и методы. Обратите внимание: Handler никогда не создаётся напрямую; этот класс служит базой для более полезных подклассов. Однако метод __init__() в подклассах должен вызывать Handler.__init__().
-
class
logging.Handler¶ -
__init__(level=NOTSET)¶ Инициализирует экземпляр
Handler, устанавливая его уровень, список фильтров в пустой список и создавая блокировку (с помощьюcreateLock()) для сериализации доступа к механизму ввода-вывода.
-
createLock()¶ Инициализирует потоковую блокировку, которую можно использовать для синхронизации доступа к низкоуровневым функциям ввода-вывода, которые могут не быть потокобезопасными.
-
acquire()¶ Захватывает блокировку потока, созданную с помощью
createLock().
-
setLevel(level)¶ Устанавливает порог для этого обработчика в level. Сообщения журнала, уровень серьёзности которых ниже level, будут игнорироваться. При создании обработчика уровень устанавливается в
NOTSET(из-за чего обрабатываются все сообщения).Список уровней приведён в разделе Logging Levels.
Изменено в версии 3.2: Параметр level теперь принимает строковое представление уровня, например 'INFO', вместо целочисленных констант, таких как
INFO.
-
addFilter(filter)¶ Добавляет указанный фильтр filter к этому обработчику.
-
removeFilter(filter)¶ Удаляет указанный фильтр filter из этого обработчика.
-
filter(record)¶ Применяет фильтры данного обработчика к записи и возвращает истинное значение, если запись должна быть обработана. Фильтры опрашиваются по очереди, пока один из них не вернёт ложное значение. Если ни один не вернул ложное значение, запись будет выдана. Если один возвращает ложное значение, обработчик не выдаст запись.
-
flush()¶ Гарантирует, что весь вывод журнала был сброшен. Эта версия ничего не делает и предназначена для реализации в подклассах.
-
close()¶ Освобождает все ресурсы, используемые обработчиком. Данная версия не выполняет вывод, но удаляет обработчик из внутреннего списка обработчиков, который закрывается при вызове
shutdown(). Подклассы должны обеспечить вызов этого метода из переопределённых методовclose().
-
handle(record)¶ Условно выдает указанную запись журнала в зависимости от фильтров, которые могли быть добавлены к обработчику. Оборачивает фактическую выдачу записи захватом/освобождением блокировки потока ввода-вывода.
-
handleError(record)¶ Этот метод должен вызываться из обработчиков, когда возникает исключение во время вызова
emit(). Если атрибут уровня модуляraiseExceptionsравенFalse, исключения молча игнорируются. Это в основном и нужно для системы журналирования – большинство пользователей не будут беспокоиться об ошибках в системе журналирования, их больше интересуют ошибки приложения. Однако вы можете заменить его на собственный обработчик, если пожелаете. Указанная запись – это та, которая обрабатывалась в момент возникновения исключения. (Значение по умолчаниюraiseExceptions–True, так как это более полезно во время разработки.)
-
format(record)¶ Выполняет форматирование записи: если задан форматировщик, использует его. В противном случае используется форматировщик по умолчанию для модуля.
-
emit(record)¶ Делает всё необходимое для фактической регистрации указанной записи журнала. Эта версия предназначена для реализации в подклассах и поэтому вызывает
NotImplementedError.
-
Список стандартных обработчиков см. в logging.handlers.
16.6.4. Объекты Formatter
Объекты Formatter имеют следующие атрибуты и методы. Они отвечают за преобразование LogRecord (обычно) в строку, которая может быть интерпретирована человеком или внешней системой. Базовый Formatter позволяет указать строку форматирования. Если она не задана, используется значение по умолчанию '%(message)s', которое просто включает сообщение из вызова логирования. Чтобы добавить дополнительную информацию в форматированный вывод (например, временную метку), читайте дальше.
Форматировщик можно инициализировать строкой форматирования, которая использует знание об атрибутах LogRecord – например, упомянутое выше значение по умолчанию использует тот факт, что сообщение и аргументы пользователя предварительно форматируются в атрибут message объекта LogRecord. Эта строка форматирования содержит стандартные ключи подстановки в стиле % языка Python. См. раздел printf-style String Formatting для получения дополнительной информации о форматировании строк.
Полезные ключи подстановки в LogRecord приведены в разделе LogRecord attributes.
-
class
logging.Formatter(fmt=None, datefmt=None, style='%')¶ Возвращает новый экземпляр класса
Formatter. Экземпляр инициализируется строкой форматирования для всего сообщения, а также строкой форматирования для части даты/времени сообщения. Если fmt не указан, используется'%(message)s'. Если datefmt не указан, используется формат, описанный в документацииformatTime().Параметр style может принимать значения '%', '{' или '$' и определяет, как\nстрока форматирования будет объединяться с данными: с помощью %-форматирования,\n
str.format()илиstring.Template. См. Использование определённых стилей форматирования во всём приложении\nдля получения дополнительной информации об использовании {}- и $-форматирования для сообщений журнала.Изменено в версии 3.2: Добавлен параметр style.
-
format(record)¶ Словарь атрибутов записи используется как операнд операции форматирования строки. Возвращается результирующая строка. Перед форматированием словаря выполняется несколько подготовительных шагов. Атрибут message записи вычисляется с помощью msg % args. Если форматирующая строка содержит
'(asctime)', то вызываетсяformatTime()для форматирования времени события. Если есть информация об исключении, она форматируется с помощьюformatException()и добавляется к сообщению. Обратите внимание, что отформатированная информация об исключении кэшируется в атрибуте exc_text. Это полезно, поскольку информацию об исключении можно сериализовать и передавать по сети, но следует соблюдать осторожность, если имеется более одного подклассаFormatter, который настраивает форматирование информации об исключении. В этом случае необходимо очищать кэшированное значение после того, как форматер выполнит своё форматирование, чтобы следующий форматер, обрабатывающий событие, не использовал кэшированное значение, а пересчитывал его заново.Если информация о стеке доступна, она добавляется после информации об исключении с использованием
formatStack()для её преобразования при необходимости.
-
formatTime(record, datefmt=None)¶ Этот метод должен вызываться из
format()форматером, который хочет использовать отформатированное время. Этот метод может быть переопределён в форматерах для любых конкретных требований, но основное поведение следующее: если указан datefmt (строка), он используется сtime.strftime()для форматирования времени создания записи. В противном случае используется формат '%Y-%m-%d %H:%M:%S,uuu', где часть uuu – значение в миллисекундах, а остальные буквы – согласно документацииtime.strftime(). Пример времени в этом формате:2003-01-23 00:29:50,411. Возвращается полученная строка.Эта функция использует настраиваемую пользователем функцию для преобразования времени создания в кортеж. По умолчанию используется
time.localtime(); чтобы изменить это для конкретного экземпляра форматера, установите атрибутconverterна функцию с той же сигнатурой, что иtime.localtime()илиtime.gmtime(). Чтобы изменить это для всех форматеров, например если требуется, чтобы все метки времени логирования отображались в GMT, установите атрибутconverterв классеFormatter.Изменено в версии 3.3: Ранее формат по умолчанию был жёстко задан, как в этом примере:
2010-09-06 22:38:15,292, где часть до запятой обрабатывается строкой форматирования strptime ('%Y-%m-%d %H:%M:%S'), а часть после запятой – значение в миллисекундах. Поскольку в strptime нет плейсхолдера для миллисекунд, значение миллисекунд добавляется с помощью другой строки форматирования,'%s,%03d'– и обе эти строки форматирования были жёстко закодированы в этом методе. С этим изменением эти строки определяются как атрибуты уровня класса, которые при необходимости могут быть переопределены на уровне экземпляра. Имена атрибутов:default_time_format(для строки форматирования strptime) иdefault_msec_format(для добавления значения миллисекунд).
-
formatException(exc_info)¶ Форматирует указанную информацию об исключении (стандартный кортеж исключения, возвращаемый
sys.exc_info()) в строку. Эта реализация по умолчанию просто используетtraceback.print_exception(). Возвращается полученная строка.
-
formatStack(stack_info)¶ Форматирует указанную информацию о стеке (строку, возвращаемую
traceback.print_stack(), но с удалённым последним символом новой строки) в строку. Эта реализация по умолчанию просто возвращает входное значение.
-
16.6.5. Объекты Filter
Filters может использоваться Handlers и Loggers для более сложной фильтрации, чем обеспечивается уровнями. Базовый класс фильтра пропускает только события, которые находятся ниже определённой точки в иерархии регистраторов. Например, фильтр, инициализированный строкой 'A.B', будет пропускать события, зарегистрированные регистраторами 'A.B', 'A.B.C', 'A.B.C.D', 'A.B.D' и т.д., но не 'A.BB', 'B.A.B' и т.д. Если инициализирован пустой строкой, пропускаются все события.
-
class
logging.Filter(name='')¶ Возвращает экземпляр класса
Filter. Если указан name, он задаёт имя регистратора, для которого, вместе с его дочерними элементами, события будут пропускаться через фильтр. Если name – пустая строка, пропускаются все события.-
filter(record)¶ Должна ли указанная запись быть залогирована? Возвращает ноль для 'нет', ненулевое значение для\n'да'. Если это уместно, запись может быть изменена на месте этим\nметодом.
-
Обратите внимание, что фильтры, прикреплённые к обработчикам, проверяются до того, как событие будет отправлено обработчиком, тогда как фильтры, прикреплённые к регистраторам, проверяются всякий раз, когда событие регистрируется (с помощью debug(), info() и т.д.), перед отправкой события обработчикам. Это означает, что события, созданные дочерними регистраторами, не будут отфильтрованы настройкой фильтра родительского регистратора, если только фильтр не был также применён к этим дочерним регистраторам.
На самом деле не требуется создавать подкласс Filter: можно передать любой экземпляр, имеющий метод filter с той же семантикой.
Изменено в версии 3.2: Не нужно создавать специализированные классы Filter или использовать другие классы с методом filter: можно использовать функцию (или другой вызываемый объект) в качестве фильтра. Логика фильтрации проверяет, есть ли у объекта фильтра атрибут filter: если да, то считается, что это Filter, и вызывается его метод filter(). В противном случае считается, что это вызываемый объект, и он вызывается с записью в качестве единственного параметра. Возвращаемое значение должно соответствовать тому, что возвращает filter().
Хотя фильтры в первую очередь предназначены для фильтрации записей по более сложным критериям, чем уровни, они видят каждую запись, обрабатываемую обработчиком или регистратором, к которому они прикреплены. Это может быть полезно, например, для подсчёта количества записей, обработанных конкретным регистратором или обработчиком, или для добавления, изменения или удаления атрибутов в обрабатываемой записи LogRecord. Очевидно, что изменение LogRecord требует осторожности, но оно позволяет внедрять контекстную информацию в журналы (см. Использование фильтров для внедрения контекстной информации).
16.6.6. Объекты LogRecord
Экземпляры LogRecord автоматически создаются Logger каждый раз, когда что-то регистрируется, и могут быть созданы вручную с помощью makeLogRecord() (например, из сериализованного события, полученного по сети).
-
class
logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)¶ Содержит всю информацию, относящуюся к регистрируемому событию.
Основная информация передаётся в
msgиargs, которые объединяются с помощьюmsg % argsдля создания поляmessageзаписи.- Параметры
name – Имя регистратора, используемого для журналирования события, представленного данной записью LogRecord. Обратите внимание, что это имя всегда будет иметь это значение, даже если событие может быть отправлено обработчиком, прикреплённым к другому (родительскому) регистратору.
level – Числовой уровень события журналирования (один из DEBUG, INFO и т.д.). Обратите внимание, что он преобразуется в два атрибута LogRecord:
levelnoдля числового значения иlevelnameдля соответствующего имени уровня.pathname – Полное имя пути исходного файла, в котором был выполнен вызов журналирования.
lineno – Номер строки в исходном файле, в котором был выполнен вызов журналирования.
msg – Сообщение описания события, возможно, форматная строка с заполнителями для переменных данных.
args – Переменные данные для объединения с аргументом msg для получения описания события.
exc_info – Кортеж исключения с текущей информацией об исключении или
None, если информация об исключении отсутствует.func – Имя функции или метода, из которого был вызван вызов журналирования.
sinfo – Текстовая строка, представляющая информацию о стеке от основания стека в текущем потоке до вызова журналирования.
-
getMessage()¶ Возвращает сообщение для экземпляра
LogRecordпосле объединения любых аргументов, предоставленных пользователем, с сообщением. Если аргумент сообщения, предоставленный пользователем при вызове регистрации, не является строкой, для преобразования в строку вызываетсяstr(). Это позволяет использовать пользовательские классы в качестве сообщений, чей метод__str__может возвращать фактическую строку формата, которая будет использоваться.
Изменено в версии 3.2: Создание
LogRecordстало более настраиваемым благодаря предоставлению фабрики для создания записи. Фабрику можно установить с помощьюgetLogRecordFactory()иsetLogRecordFactory()(см. это для сигнатуры фабрики).Эту функциональность можно использовать для внедрения собственных значений в объект LogRecord во время его создания. Можно использовать следующий шаблон:
pythonold_factory = logging.getLogRecordFactory() def record_factory(*args, **kwargs): record = old_factory(*args, **kwargs) record.custom_attribute = 0xdecafbad return record logging.setLogRecordFactory(record_factory)При таком шаблоне можно объединять несколько фабрик в цепочку, и до тех пор, пока они не перезаписывают атрибуты друг друга или случайно не перезаписывают стандартные атрибуты, перечисленные выше, не должно возникнуть неожиданных проблем.
16.6.7. Атрибуты LogRecord
LogRecord имеет ряд атрибутов, большинство из которых получены из параметров конструктора. (Обратите внимание, что имена не всегда точно соответствуют между параметрами конструктора LogRecord и атрибутами LogRecord.) Эти атрибуты можно использовать для объединения данных из записи в строку формата. В следующей таблице перечислены (в алфавитном порядке) имена атрибутов, их значения и соответствующий заполнитель в строке формата в стиле %.
Если используется форматирование {} (str.format()), в качестве заполнителя в строке формата можно использовать {attrname}. Если используется $-форматирование (string.Template), используется форма ${attrname}. В обоих случаях, конечно, attrname заменяется на фактическое имя атрибута.
В случае форматирования {} можно указать флаги форматирования, разместив их после имени атрибута, отделив двоеточием. Например: заполнитель {msecs:03d} отформатирует значение миллисекунд 4 как 004. Для получения полной информации о доступных параметрах см. документацию str.format().
Имя атрибута |
Формат |
Описание |
|---|---|---|
args |
Вам не нужно форматировать это вручную. |
Кортеж аргументов, объединённых в |
asctime |
|
Человекочитаемое время создания |
created |
|
Время создания |
exc_info |
Вам не нужно форматировать это вручную. |
Кортеж исключения (как в |
filename |
|
Часть имени файла из |
funcName |
|
Имя функции, содержащей вызов логирования. |
levelname |
|
Текстовый уровень логирования для сообщения
( |
levelno |
|
Числовой уровень логирования для сообщения
( |
lineno |
|
Номер строки исходного кода, где был сделан вызов логирования (если доступен). |
message |
|
Записанное сообщение, вычисляемое как |
модуль |
|
Модуль (часть имени из |
msecs |
|
Миллисекундная часть времени создания
|
msg |
Вам не нужно форматировать это вручную. |
Строка формата, переданная в исходный
вызов логирования. Объединяется с |
имя |
|
Имя регистратора, используемого для логирования вызова. |
pathname |
|
Полный путь к исходному файлу, где был сделан вызов логирования (если доступен). |
процесс |
|
Идентификатор процесса (если доступен). |
processName |
|
Имя процесса (если доступно). |
relativeCreated |
|
Время в миллисекундах, когда был создан LogRecord, относительно времени загрузки модуля logging. |
stack_info |
Вам не нужно форматировать это вручную. |
Информация о фреймах стека (если доступна) от дна стека в текущем потоке, вплоть до и включая фрейм вызова журналирования, который привёл к созданию этой записи. |
поток |
|
Идентификатор потока (если доступен). |
threadName |
|
Имя потока (если доступно). |
Изменено в версии 3.1: processName был добавлен.
16.6.8. Объекты LoggerAdapter
Экземпляры LoggerAdapter используются для удобной передачи контекстной информации в вызовы логирования. Пример использования см. в разделе добавление контекстной информации в вывод лога.
-
class
logging.LoggerAdapter(logger, extra)¶ Возвращает экземпляр
LoggerAdapter, инициализированный базовым экземпляромLoggerи объектом, похожим на словарь.-
process(msg, kwargs)¶ Изменяет сообщение и/или именованные аргументы, передаваемые в вызов логирования, для вставки контекстной информации. Эта реализация берёт объект, переданный как extra в конструктор, и добавляет его в kwargs с ключом 'extra'. Возвращаемое значение – кортеж (msg, kwargs), содержащий (возможно изменённые) версии переданных аргументов.
-
В дополнение к вышеуказанному, LoggerAdapter поддерживает следующие методы Logger: debug(), info(), warning(), error(), exception(), critical(), log(), isEnabledFor(), getEffectiveLevel(), setLevel() и hasHandlers(). Эти методы имеют те же сигнатуры, что и их аналоги в Logger, поэтому вы можете использовать экземпляры обоих типов взаимозаменяемо.
Изменено в версии 3.2: Методы isEnabledFor(), getEffectiveLevel(), setLevel() и hasHandlers() были добавлены в LoggerAdapter. Эти методы делегируют выполнение базовому логгеру.
16.6.9. Потокобезопасность
Модуль logging спроектирован так, чтобы быть потокобезопасным без необходимости выполнения каких-либо специальных действий со стороны его пользователей. Это достигается за счет использования блокировок потоков: одна блокировка обеспечивает последовательный доступ к общим данным модуля, и каждый обработчик также создает блокировку для последовательного доступа к своему базовому вводу-выводу.
Если вы реализуете асинхронные обработчики сигналов с помощью модуля signal, вы можете не иметь возможности использовать логирование из таких обработчиков. Это связано с тем, что реализации блокировок в модуле threading не всегда реентерабельны и поэтому не могут быть вызваны из таких обработчиков сигналов.
16.6.10. Функции уровня модуля
В дополнение к классам, описанным выше, существует ряд функций уровня модуля.
-
logging.getLogger(name=None)¶ Возвращает логгер с указанным именем или, если имя равно
None, возвращает\nлоггер, который является корневым логгером иерархии. Если указано, имя обычно\nпредставляет собой иерархическое имя, разделённое точками, например ‘a’, ‘a.b’ или ‘a.b.c.d’.\nВыбор этих имён полностью зависит от разработчика, использующего логирование.Все вызовы этой функции с одним и тем же именем возвращают один и тот же экземпляр регистратора. Это означает, что экземпляры регистратора никогда не нужно передавать между разными частями приложения.
-
logging.getLoggerClass()¶ Возвращает либо стандартный класс
Logger, либо последний класс, переданный вsetLoggerClass(). Эту функцию можно вызывать из определения нового класса, чтобы установка пользовательского классаLoggerне отменяла изменения, уже внесённые другим кодом. Например:pythonclass MyLogger(logging.getLoggerClass()): # ... override behaviour here
-
logging.getLogRecordFactory()¶ Возвращает вызываемый объект, который используется для создания объекта
LogRecord.Новое в версии 3.2: Эта функция предоставлена вместе с
setLogRecordFactory(),\nчтобы дать разработчикам больше контроля над тем, как конструируетсяLogRecord\nпредставляющий событие логирования.Смотрите
setLogRecordFactory()для получения дополнительной информации о том, как вызывается фабрика.
-
logging.debug(msg, *args, **kwargs)¶ Регистрирует сообщение с уровнем
DEBUGв корневом логгере. msg – это строка форматирования сообщения, а args – аргументы, которые объединяются с msg с помощью оператора форматирования строк. (Обратите внимание, что это означает возможность использования ключевых слов в строке форматирования вместе с единственным аргументом-словарём.)В kwargs проверяются три именованных аргумента: exc_info – если он не равен false, информация об исключении добавляется в сообщение лога. Если передаётся кортеж исключения (в формате, возвращаемом
sys.exc_info()) или экземпляр исключения, используется он; в противном случае вызываетсяsys.exc_info()для получения информации об исключении.Второй необязательный именованный аргумент – stack_info, по умолчанию
False. Если true, в сообщение журнала добавляется информация о стеке, включая сам вызов журналирования. Обратите внимание, что это не та же информация о стеке, что отображается при указании exc_info: первая – это фреймы стека от дна стека до вызова журналирования в текущем потоке, тогда как вторая – это информация о фреймах стека, которые были развёрнуты после исключения, при поиске обработчиков исключений.Можно указать stack_info независимо от exc_info, например, чтобы просто показать, как был достигнут определённый участок кода, даже если никаких исключений не возникало. Фреймы стека выводятся после строки заголовка, которая гласит:
textStack (most recent call last):Это имитирует
Traceback (most recent call last):, который используется при отображении фреймов исключений.Третий необязательный именованный аргумент – extra, который можно использовать для передачи словаря, заполняющего __dict__ объекта LogRecord, создаваемого для события логирования, пользовательскими атрибутами. Затем эти пользовательские атрибуты можно использовать по своему усмотрению. Например, их можно встраивать в сообщения. Пример:
pythonFORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s' logging.basicConfig(format=FORMAT) d = {'clientip': '192.168.0.1', 'user': 'fbloggs'} logging.warning('Protocol problem: %s', 'connection reset', extra=d)выведет примерно следующее:
text2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection resetКлючи в словаре, передаваемом в extra, не должны совпадать с ключами, используемыми системой логирования. (См. документацию
Formatterдля получения дополнительной информации о том, какие ключи используются системой логирования.)При использовании этих атрибутов в сообщениях необходимо соблюдать осторожность. В приведённом выше примере, например,
Formatterнастроен со строкой форматирования, которая ожидает атрибуты 'clientip' и 'user' в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет зарегистрировано, так как возникнет исключение форматирования строки. Поэтому в данном случае необходимо всегда передавать словарь extra с этими ключами.Хотя это может раздражать, данная возможность предназначена для использования в специализированных ситуациях, например, на многопоточных серверах, где один и тот же код выполняется во множестве контекстов, и возникающие интересные условия зависят от этого контекста (такие как IP-адрес удалённого клиента и имя аутентифицированного пользователя в приведённом выше примере). В таких обстоятельствах, скорее всего, будут использоваться специализированные
Formatterс определённымиHandler.Новое в версии 3.2: Добавлен параметр stack_info.
-
logging.info(msg, *args, **kwargs)¶ Регистрирует сообщение с уровнем
INFOв корневом логгере. Аргументы интерпретируются как дляdebug().
-
logging.warning(msg, *args, **kwargs)¶ Регистрирует сообщение с уровнем
WARNINGв корневом логгере. Аргументы интерпретируются как дляdebug().Примечание
Существует устаревшая функция
warn, которая функционально идентичнаwarning. Посколькуwarnустарела, не используйте её – вместо неё используйтеwarning.
-
logging.error(msg, *args, **kwargs)¶ Регистрирует сообщение с уровнем
ERRORв корневом логгере. Аргументы интерпретируются как дляdebug().
-
logging.critical(msg, *args, **kwargs)¶ Регистрирует сообщение с уровнем
CRITICALв корневом логгере. Аргументы интерпретируются как дляdebug().
-
logging.exception(msg, *args, **kwargs)¶ Регистрирует сообщение с уровнем
ERRORв корневом логгере. Аргументы интерпретируются как дляdebug(). В сообщение добавляется информация об исключении. Эту функцию следует вызывать только из обработчика исключений.
-
logging.log(level, msg, *args, **kwargs)¶ Регистрирует сообщение с уровнем level в корневом логгере. Остальные аргументы интерпретируются как для
debug().Примечание
Вышеупомянутые удобные функции модуля верхнего уровня, которые делегируют корневому логгеру, вызывают
basicConfig(), чтобы гарантировать наличие хотя бы одного обработчика. Из-за этого их не следует использовать в потоках в версиях Python ранее 2.7.1 и 3.2, если только до запуска потоков в корневой логгер не был добавлен хотя бы один обработчик. В более ранних версиях Python из-за недостатка потокобезопасности вbasicConfig()это может (в редких случаях) привести к многократному добавлению обработчиков в корневой логгер, что, в свою очередь, может привести к появлению нескольких сообщений для одного события.
-
logging.disable(lvl=CRITICAL)¶ Предоставляет переопределяющий уровень lvl для всех регистраторов, который имеет приоритет над собственным уровнем регистратора. Когда возникает необходимость временно снизить интенсивность вывода журнала во всем приложении, эта функция может быть полезна. Её действие – отключать все вызовы журналирования с серьезностью lvl и ниже; если вызвать её со значением INFO, то все события INFO и DEBUG будут отброшены, а события серьезности WARNING и выше будут обработаны в соответствии с эффективным уровнем регистратора. Если вызывается
logging.disable(logging.NOTSET), этот переопределяющий уровень удаляется, и вывод журнала снова зависит от эффективных уровней отдельных регистраторов.Обратите внимание: если вы определили какой-либо пользовательский уровень журналирования выше
CRITICAL(это не рекомендуется), вы не сможете полагаться на значение по умолчанию для параметра lvl, а должны будете явно указать подходящее значение.Изменено в версии 3.7: Параметр lvl по умолчанию получил значение
CRITICAL. См. Issue #28524 для получения дополнительной информации об этом изменении.
-
logging.addLevelName(lvl, levelName)¶ Связывает уровень lvl с текстом levelName во внутреннем словаре, который используется для сопоставления числовых уровней с текстовым представлением, например, когда
Formatterформатирует сообщение. Эта функция также может использоваться для определения собственных уровней. Единственные ограничения: все используемые уровни должны быть зарегистрированы с помощью этой функции, уровни должны быть положительными целыми числами и должны возрастать с увеличением серьезности.Примечание
Если вы собираетесь определять собственные уровни, обратитесь к разделу Пользовательские уровни.
-
logging.getLevelName(lvl)¶ Возвращает текстовое представление уровня журналирования lvl. Если уровень является одним из предопределенных уровней
CRITICAL,ERROR,WARNING,INFOилиDEBUG, то возвращается соответствующая строка. Если вы связали уровни с именами с помощьюaddLevelName(), то возвращается имя, которое вы связали с lvl. Если передан числовой уровень, соответствующий одному из определенных уровней, возвращается соответствующее строковое представление. В противном случае возвращается строка 'Level %s' % lvl.Примечание
Уровни внутри являются целыми числами (поскольку их необходимо сравнивать в логике логирования). Эта функция используется для преобразования между целочисленным уровнем и именем уровня, отображаемым в отформатированном выводе журнала с помощью спецификатора формата
%(levelname)s(см. атрибуты LogRecord).Изменено в версии 3.4: В версиях Python до 3.4 этой функции также можно было передавать текстовый уровень, и она возвращала соответствующее числовое значение уровня. Это недокументированное поведение было признано ошибкой и удалено в Python 3.4, но восстановлено в 3.4.2 для сохранения обратной совместимости.
-
logging.makeLogRecord(attrdict)¶ Создаёт и возвращает новый экземпляр
LogRecord, атрибуты которого определяются attrdict. Эта функция полезна для получения сериализованного (pickled) словаря атрибутовLogRecord, отправленного через сокет, и восстановления его как экземпляраLogRecordна принимающей стороне.
-
logging.basicConfig(**kwargs)¶ Выполняет базовую настройку системы логирования, создавая
StreamHandlerсFormatterпо умолчанию и добавляя его в корневой логгер. Функцииdebug(),info(),warning(),error()иcritical()будут автоматически вызыватьbasicConfig(), если для корневого логгера не определены обработчики.Эта функция ничего не делает, если для корневого регистратора уже настроены обработчики.
Примечание
Данную функцию следует вызывать из главного потока до запуска других потоков. В версиях Python до 2.7.1 и 3.2, если эта функция вызывается из нескольких потоков, возможно (в редких случаях), что обработчик будет добавлен к корневому логгеру более одного раза, что приведёт к неожиданным результатам, таким как дублирование сообщений в логе.
Поддерживаются следующие именованные аргументы.
Формат
Описание
filename
Указывает, что должен быть создан FileHandler, использующий указанное имя файла, а не StreamHandler.
filemode
Если указан filename, открыть файл в этом mode. По умолчанию
'a'.format
Использует указанную строку формата для обработчика.
datefmt
Использовать указанный формат даты/времени, принимаемый
time.strftime().style
Если указан format, использовать этот стиль для строки формата. Один из
'%','{'или'$'для printf-стиля,str.format()илиstring.Templateсоответственно. По умолчанию'%'.уровень
Установить уровень корневого логгера в указанный уровень.
поток данных
Использует указанный поток для инициализации StreamHandler. Обратите внимание, что этот аргумент несовместим с filename – если оба присутствуют, возбуждается
ValueError.обработчики
Если указан, это должен быть итерируемый объект с уже созданными обработчиками для добавления в корневой регистратор. Любые обработчики, для которых еще не задан форматировщик, получат форматировщик по умолчанию, созданный в этой функции. Обратите внимание, что этот аргумент несовместим с filename или stream – если указаны оба, возбуждается
ValueError.Изменено в версии 3.2: Был добавлен аргумент style.
Изменено в версии 3.3: Был добавлен аргумент handlers. Были добавлены дополнительные проверки для выявления ситуаций, когда указаны несовместимые аргументы (например, handlers вместе с stream или filename, или stream вместе с filename).
-
logging.shutdown()¶ Сообщает системе логирования о необходимости выполнить упорядоченное завершение работы, сбрасывая и закрывая все обработчики. Этот вызов следует производить при завершении приложения, и после этого вызова не следует использовать систему логирования.
-
logging.setLoggerClass(klass)¶ Указывает системе логирования использовать класс klass при создании экземпляра регистратора. Класс должен определять
__init__()таким образом, чтобы требовался только аргумент name, и__init__()должен вызыватьLogger.__init__(). Эта функция обычно вызывается до создания экземпляров регистраторов приложениями, которым требуется пользовательское поведение регистратора.
-
logging.setLogRecordFactory(фабрика)¶ Устанавливает вызываемый объект, который используется для создания
LogRecord.- Параметры
factory – вызываемый объект-фабрика, используемый для создания экземпляра записи журнала.
Новое в версии 3.2: Эта функция предоставляется вместе с
getLogRecordFactory(), чтобы разработчики могли лучше контролировать созданиеLogRecord, представляющего событие логирования.Фабрика имеет следующую сигнатуру:
factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)- имя
Имя регистратора.
- уровень
Уровень логирования (числовой).
- fn
Полное имя пути к файлу, в котором был сделан вызов логирования.
- lno
Номер строки в файле, в котором был сделан вызов логирования.
- msg
Сообщение логирования.
- args
Аргументы для сообщения логирования.
- exc_info
Кортеж исключения или
None.- func
Имя функции или метода, вызвавшего вызов логирования.
- sinfo
Трассировка стека, такая как предоставляется
traceback.print_stack(), показывающая иерархию вызовов.- kwargs
Дополнительные именованные аргументы.
16.6.11. Атрибуты уровня модуля
-
logging.lastResort¶ Через этот атрибут доступен «обработчик последней надежды». Это
StreamHandler, пишущий вsys.stderrс уровнемWARNINGи используемый для обработки событий логирования при отсутствии какой-либо конфигурации логирования. Конечный результат – просто вывод сообщения вsys.stderr. Это заменяет более раннее сообщение об ошибке: «для регистратора XYZ не найдено ни одного обработчика». Если вам по какой-то причине нужно прежнее поведение,lastResortможно установить вNone.Новое в версии 3.2.
16.6.12. Интеграция с модулем warnings
Функция captureWarnings() может использоваться для интеграции logging с модулем warnings.
-
logging.captureWarnings(захват)¶ Эта функция используется для включения и выключения захвата предупреждений системой логирования.
Если capture равно
True, предупреждения, выпущенные модулемwarnings, будут перенаправлены в систему логирования. В частности, предупреждение будет отформатировано с помощьюwarnings.formatwarning(), и результирующая строка будет записана в регистратор с именем'py.warnings'с уровнем важностиWARNING.Если capture равно
False, перенаправление предупреждений в систему логирования прекратится, и предупреждения будут перенаправляться в исходные места назначения (т.е. те, которые действовали до вызоваcaptureWarnings).
Смотрите также
- Модуль
logging.config API конфигурации для модуля логирования.
- Модуль
logging.handlers Полезные обработчики, включённые в модуль логирования.
- PEP 282 – Система логирования
Предложение, описывающее эту функциональность для включения в стандартную библиотеку Python.
- Оригинальный пакет логирования Python
Это исходный код для пакета
logging. Версия пакета, доступная на этом сайте, подходит для использования с Python 1.5.2, 2.1.x и 2.2.x, которые не включают пакетloggingв стандартную библиотеку.