logging — Система ведения журналов для Python
Исходный код: Lib/logging/__init__.py
В данном модуле определены функции и классы, реализующие гибкую систему ведения журналов событий для приложений и библиотек.
Основное преимущество использования API ведения журналов, предоставляемого стандартным модулем библиотеки, заключается в том, что все модули Python могут участвовать в ведении журналов, поэтому журнал вашего приложения может включать собственные сообщения, интегрированные с сообщениями модулей сторонних разработчиков.
Модуль предоставляет множество функциональных возможностей и гибкости. Если вы не знакомы с ведением журналов, лучший способ разобраться с ним — изучить руководства (см. ссылки справа).
Основные классы, определенные модулем, вместе со своими функциями, перечислены ниже.
- Логгеры предоставляют интерфейс, который напрямую используется кодом приложения.
- Обработчики отправляют записи журнала (созданные логгерами) в соответствующее место назначения.
- Фильтры обеспечивают более тонкую возможность определения записей журнала, которые необходимо выводить.
- Форматировщики определяют макет записей журнала в итоговом выводе.
Объекты логгеров
Логгеры имеют следующие атрибуты и методы. Обратите внимание, что логгеры НИКОГДА не следует создавать напрямую, а всегда через функцию модуля 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, сообщения логгирования не передаются обработчикам логгеров предков.
Рассмотрим пример: если свойство propagate логгера с именем
A.B.Cимеет значение true, любое событие, зарегистрированное в логгереA.B.Cс помощью метода, такого какlogging.getLogger('A.B.C').error(...), [при условии прохождения уровня и настроек фильтра этого логгера] будет передано в свою очередь любым обработчикам, прикреплённым к логгерам с именамиA.B,Aи корневому логгере после того, как будет передано любым обработчикам, прикреплённым кA.B.C. Если какой-либо логгер в цепочкеA.B.C,A.B,Aимеет значение своего свойстваpropagatefalse, то это последний логгер, чьи обработчики получат событие для обработки, и распространение прекратится на этом этапе.Конструктор устанавливает это свойство в
True.Примечание
Если вы прикрепляете обработчик к логгеру и одному или нескольким его предкам, он может выдать одну и ту же запись несколько раз. В общем случае вам не нужно прикреплять обработчик к нескольким логгерам — если вы прикрепите его к соответствующему логгере, который стоит выше в иерархии логгеров, он увидит все события, зарегистрированные всеми дочерними логгерами, при условии, что их значение propagate оставлено
True. Типичный сценарий — прикрепление обработчиков только к корневому логгере и передача остального с помощью распространения.
-
setLevel(level) -
Устанавливает порог для этого логгера в уровень. Сообщения логгирования, которые менее серьёзные, чем уровень, будут игнорироваться; сообщения логгирования, имеющие уровень уровень или выше, будут выведены любым обработчиком или обработчиками, обслуживающими этот логгер, если уровень обработчика не установлен выше, чем уровень.
При создании логгера уровень устанавливается в
NOTSET(что вызывает обработку всех сообщений, когда логгер является корневым логгером, или делегирование родительскому логгере, когда логгер не является корневым). Обратите внимание, что корневой логгер создаётся с уровнемWARNING.Термин «делегирование родительскому логгере» означает, что если у логгера уровень NOTSET, его цепочка предковых логгеров просматривается до тех пор, пока не будет найден предок с уровнем, отличным от NOTSET, или не будет достигнут корень.
Если предок с уровнем, отличным от NOTSET, будет найден, уровень этого предка рассматривается как эффективный уровень логгера, с которого начался поиск предка, и используется для определения того, как обрабатывается событие логгирования.
Если корень достигнут и его уровень равен NOTSET, все сообщения будут обработаны. В противном случае, уровень корня будет использован как эффективный уровень.
См. Уровни логгирования для списка уровней.
Изменено в версии 3.2: Параметр уровень теперь принимает строковое представление уровня, например, ‘INFO’, как альтернативу целочисленным константам, например,
INFO. Однако обратите внимание, что уровни хранятся внутри как целые числа, а методы, такие как, например,getEffectiveLevel()иisEnabledFor(), будут возвращать/ожидать в качестве аргумента целые числа.
-
isEnabledFor(level) -
Указывает, будет ли сообщение с уровнем уровень обработано этим логгером. Этот метод сначала проверяет уровень модульного уровня, установленный
logging.disable(level), а затем эффективный уровень логгера, определяемый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 с помощью оператора форматирования строк. (Обратите внимание, что это означает, что вы можете использовать ключевые слова в строке формата вместе с единственным аргументом-словарём.) Никаких операций форматирования % не выполняется над msg, если args не указаны.В kwargs проверяются четыре ключевых аргумента: exc_info, stack_info, stacklevel и extra.
Если exc_info не равно false, это добавит информацию об исключении в сообщение логгирования. Если указана кортеж исключения (в формате, возвращаемом
sys.exc_info()) или экземпляр исключения, он используется; в противном случае, вызываетсяsys.exc_info()для получения информации об исключении.Второй необязательный ключевой аргумент — stack_info, который по умолчанию равен
False. Если true, информация о стеке добавляется в сообщение логгирования, включая сам вызов логгирования. Обратите внимание, что это не та информация о стеке, которая отображается при указании exc_info: первая — кадры стека снизу до вызова логгирования в текущей нити, а вторая — информация о кадрах стека, которые были развёрнуты после исключения при поиске обработчиков исключений.Вы можете указать stack_info независимо от exc_info, например, чтобы просто показать, как вы дошли до определённой точки в своём коде, даже если исключения не были подняты. Кадры стека печатаются после заголовка:
Stack (most recent call last):
Это имитирует
Traceback (most recent call last):при отображении кадров исключения.Третий необязательный ключевой аргумент — stacklevel, по умолчанию
1. Если больше 1, соответствующее количество кадров стека пропускается при вычислении номера строки и имени функции, установленных вLogRecord, созданном для события логгирования. Это может использоваться в помощниках логгирования, чтобы имя функции, имя файла и номер строки, записанные, не были информацией для вспомогательной функции/метода, а для его вызывающего. Название этого параметра отражает эквивалентный параметр в модулеwarnings.Четвёртый ключевой аргумент — extra, который может использоваться для передачи словаря, который используется для заполнения __dict__
LogRecord, созданного для события логгирования, пользовательскими атрибутами. Эти пользовательские атрибуты могут использоваться по вашему усмотрению. Например, они могут быть включены в сообщения логгирования. Например:FORMAT = '%(asctime)s %(clientip)-15s %(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)выведет что-то вроде
2006-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 теперь может принимать экземпляры исключений.
Изменено в версии 3.8: Добавлен параметр stacklevel.
-
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(level, msg, *args, **kwargs) -
Записывает сообщение с целочисленным уровнем level в этот логгер. Остальные аргументы интерпретируются так же, как для
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, stacklevel=1) -
Определяет имя файла и номер строки вызывающей функции. Возвращает имя файла, номер строки, имя функции и информацию о стеке в виде кортежа из 4 элементов. Информация о стеке возвращается как
None, если stack_info не равноTrue.Параметр stacklevel передаётся из кода, вызывающего
debug()и других API. Если он больше 1, избыточное значение используется для пропуска кадров стека перед определением возвращаемых значений. Это обычно полезно при вызове API логгирования из вспомогательного/оберточного кода, чтобы информация в журнале событий относилась не к вспомогательному/оберточному коду, а к коду, который его вызывает.
-
handle(record) -
Обрабатывает запись, передавая её всем обработчикам, связанным с этим логгером и его предками (до тех пор, пока не будет найдено значение propagate равное false). Этот метод используется для распакованных записей, полученных из сокета, а также для созданных локально. Фильтрация на уровне логгера применяется с помощью
filter().
-
makeRecord(name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None) -
Это фабричный метод, который может быть переопределён в подклассах для создания специализированных экземпляров
LogRecord.
-
hasHandlers() -
Проверяет, есть ли у этого логгера какие-либо обработчики. Это делается путем поиска обработчиков в этом логере и его родительских логгерах в иерархии логгеров. Возвращает
True, если обработчик был найден, иначеFalse. Поиск по иерархии прекращается, как только встречается логгер с атрибутом ‘propagate’, установленным в false — это последний логгер, который проверяется на наличие обработчиков.Новое в версии 3.2.
Изменено в версии 3.7: Логгеры теперь можно сериализовать и десериализовать.
-
Уровни логгирования
Числовые значения уровней логгирования приведены в следующей таблице. Они в первую очередь интересны, если вы хотите определить свои собственные уровни и хотите, чтобы они имели определённые значения относительно предопределённых уровней. Если вы определите уровень с тем же числовым значением, он перепишет предопределённое значение; предопределённое имя будет потеряно.
Уровень | Числовое значение |
|---|---|
| 50 |
| 40 |
| 30 |
| 20 |
| 10 |
| 0 |
Объекты обработчиков
Обработчики имеют следующие атрибуты и методы. Обратите внимание, что Handler никогда напрямую не создаётся; этот класс служит основой для более полезных подклассов. Однако метод __init__() в подклассах должен вызывать метод Handler.__init__().
-
class logging.Handler -
-
__init__(level=NOTSET) -
Инициализирует экземпляр
Handler, установив его уровень, задав список фильтров в пустой список и создав блокировку (используяcreateLock()) для сериализации доступа к механизму ввода/вывода.
-
createLock() -
Инициализирует блокировку потока, которая может использоваться для сериализации доступа к базовой функциональности ввода/вывода, которая может быть не потокобезопасной.
-
acquire() -
Получает блокировку потока, созданную с помощью
createLock().
-
release() -
Освобождает блокировку потока, полученную с помощью
acquire().
-
setLevel(level) -
Устанавливает порог для этого обработчика на уровень. Сообщения об ошибках, которые менее серьёзны, чем уровень, будут игнорироваться. При создании обработчика уровень устанавливается в
NOTSET(что приводит к обработке всех сообщений).Список уровней см. в разделе Уровни регистрации.
Изменено в версии 3.2: Параметр уровень теперь принимает строковое представление уровня, например ‘INFO’, в качестве альтернативы целочисленным константам, таким как
INFO.
-
setFormatter(fmt) -
Устанавливает
Formatterдля этого обработчика на fmt.
-
addFilter(filter) -
Добавляет указанный фильтр filter в этот обработчик.
-
removeFilter(filter) -
Удаляет указанный фильтр filter из этого обработчика.
-
filter(record) -
Применяет фильтры этого обработчика к записи и возвращает
Trueесли запись должна быть обработана. Фильтры проверяются по очереди, пока один из них не вернёт значение false. Если ни один из них не вернёт значение false, запись будет выведена. Если один вернёт значение false, обработчик не выведет запись.
-
flush() -
Убедитесь, что весь вывод регистрации сброшен. Эта версия ничего не делает и предназначена для реализации подклассами.
-
close() -
Очистить используемые обработчиком ресурсы. Эта версия не производит вывод, но удаляет обработчик из внутреннего списка обработчиков, который закрывается при вызове
shutdown(). Подклассы должны убедиться, что это выполняется из переопределённых методовclose().
-
handle(record) -
Условно выводит указанную запись регистрации, в зависимости от фильтров, которые могут быть добавлены в обработчик. Оборачивает фактическое выведение записи с помощью получения/освобождения блокировки потока ввода/вывода.
-
handleError(record) -
Этот метод должен вызываться из обработчиков, когда во время вызова
emit()возникает исключение. Если модульный атрибутraiseExceptionsравенFalse, исключения игнорируются без звука. Это то, что в основном нужно для системы регистрации – большинство пользователей не заботятся об ошибках в системе регистрации, их больше интересуют ошибки приложения. Однако вы можете заменить это на пользовательский обработчик, если хотите. Указанная запись – это запись, которая обрабатывалась во время возникновения исключения. (Значение по умолчанию дляraiseExceptions–True, так как это полезнее во время разработки).
-
format(record) -
Выполнить форматирование записи – если установлено форматирование, использовать его. В противном случае использовать форматирование по умолчанию для модуля.
-
emit(record) -
Выполнить все необходимые действия для фактического протоколирования указанной записи протоколирования. Эта версия предназначена для реализации подклассами, поэтому вызывает
NotImplementedError.
-
Список стандартных обработчиков см. в logging.handlers.
Объекты форматирования
Formatter имеют следующие атрибуты и методы. Они отвечают за преобразование LogRecord (обычно) в строку, которую можно интерпретировать человеком или внешней системой. Базовый Formatter позволяет указать строку форматирования. Если она не указана, используется значение по умолчанию '%(message)s', которое просто включает сообщение в вызове регистрации.
Форматировщик может быть инициализирован строкой форматирования, которая использует данные LogRecord - например, значение по умолчанию, использующее то, что сообщение пользователя и аргументы предварительно отформатированы в атрибут message объекта LogRecord. Эта строка форматирования содержит стандартные ключи Python-стиля %-отображения. См. раздел Форматирование строк в стиле printf для получения дополнительной информации о форматировании строк.
Полезные ключи отображения в LogRecord приведены в разделе Атрибуты LogRecord.
-
class logging.Formatter(fmt=None, datefmt=None, style='%', validate=True) -
Возвращает новый экземпляр класса
Formatter. Экземпляр инициализируется строкой форматирования для всего сообщения, а также строкой форматирования для части даты/времени сообщения. Если fmt не указан, используется'%(message)s'. Если datefmt не указан, используется формат, описанный в документацииformatTime().Параметр style может принимать значения ‘%’, ‘{’ или ‘$’ и определяет, как строка форматирования будет объединена со своими данными: с использованием %-форматирования,
str.format()илиstring.Template. Это относится только к строке форматирования fmt (например,'%(message)s'или{message}), а не к самим лог-сообщениям, передаваемым вLogger.debugи т.д.; см. Использование определенных стилей форматирования во всей вашей программе для получения дополнительной информации об использовании {- и $-форматирования для лог-сообщений.Изменено в версии 3.2: Добавлен параметр style.
Изменено в версии 3.8: Добавлен параметр validate. Некорректный или несовместимый стиль и fmt приведут к ошибке
ValueError. Например:logging.Formatter('%(asctime)s - %(message)s', 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(). Чтобы изменить его для всех форматировщиков, например, если вы хотите, чтобы все лог-времена отображались по Гринвичу, установите атрибут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(для добавления значения миллисекунд).Изменено в версии 3.9:
default_msec_formatможет бытьNone.
-
formatException(exc_info) -
Форматирует указанную информацию об исключении (стандартную кортеж исключения, возвращаемый
sys.exc_info()) как строку. Эта реализация по умолчанию просто используетtraceback.print_exception(). Возвращается результирующая строка.
-
formatStack(stack_info) -
Форматирует указанную информацию о стеке вызовов (строка, возвращаемая
traceback.print_stack(), но с последней новой строкой удалена) как строку. Эта реализация по умолчанию просто возвращает входное значение.
-
Объекты фильтрации
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. Если указано имя, оно задаёт имя логгера, который вместе со своими дочерними логгерами будет допускать свои события через фильтр. Если имя пустая строка, допускаются все события.-
filter(record) -
Должен ли указанный элемент записи быть записан в журнал? Возвращает ноль для отказа и ненулевое значение для согласия. Если это уместно, метод может изменить запись на месте.
-
Обратите внимание, что фильтры, прикреплённые к обработчикам, проверяются перед тем, как обработчик генерирует событие, тогда как фильтры, прикреплённые к логгерам, проверяются каждый раз, когда регистрируется событие (используя debug(), info() и т. д.), прежде чем отправлять событие обработчикам. Это означает, что события, которые были сгенерированы дочерними логгерами, не будут отфильтрованы настройками фильтра логгера, если фильтр также не был применён к этим дочерним логгерам.
Вам фактически не нужно создавать подкласс Filter: вы можете передать любой экземпляр, у которого есть метод filter с теми же семантиками.
Изменено в версии 3.2: Вам не нужно создавать специализированные классы Filter, или использовать другие классы с методом filter: вы можете использовать функцию (или другой вызываемый объект) в качестве фильтра. Логика фильтрации проверит, имеет ли объект фильтра атрибут filter: если есть, предполагается, что это Filter и вызывается его метод filter(). В противном случае предполагается, что это вызываемый объект, и он вызывается с записью в качестве единственного параметра. Возвращаемое значение должно соответствовать возвращаемому значением filter().
Хотя фильтры в основном используются для фильтрации записей на основе более сложных критериев, чем уровни, они видят каждую запись, которая обрабатывается обработчиком или логгером, к которому они прикреплены: это может быть полезно, если вы хотите выполнить такие действия, как подсчёт количества записей, обработанных конкретным логгером или обработчиком, или добавить, изменить или удалить атрибуты в LogRecord, который обрабатывается. Очевидно, изменение LogRecord необходимо производить с осторожностью, но это позволяет вводить контекстную информацию в журналы (см. Использование фильтров для предоставления контекстной информации).
Объекты записей журнала
LogRecord создаются автоматически Logger каждый раз, когда что-то регистрируется, и могут быть созданы вручную с помощью makeLogRecord() (например, из сериализованного события, полученного через сеть).
-
class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None) -
Содержит всю информацию, относящуюся к регистрируемому событию.
Основная информация передаётся в
msgиargs, которые объединяются с помощьюmsg % argsдля создания поляmessageзаписи.- Параметры
-
- имя – Имя логгера, используемого для регистрации события, представленного этой записью журнала. Обратите внимание, что это имя всегда будет иметь это значение, даже если оно может быть передано обработчиком, прикреплённым к другому (предковому) логгеру.
-
уровень – Численный уровень события регистрации журнала (один из DEBUG, INFO и т. д.) Обратите внимание, что это преобразуется в два атрибута LogRecord:
levelnoдля числового значения иlevelnameдля соответствующего имени уровня. - путь – Полный путь к исходному файлу, где был сделан вызов регистрации журнала.
- строка – Номер строки в исходном файле, где был сделан вызов регистрации журнала.
- сообщение – Сообщение об описании события, возможно, строка формата с плейсхолдерами для переменных данных.
- аргументы – Переменные данные для слияния в аргумент сообщения для получения описания события.
-
exc_info – Кортеж исключения с текущей информацией об исключении или
Noneесли информация об исключении недоступна. - функция – Имя функции или метода, из которого был вызван вызов регистрации журнала.
- sinfo – Строка текста, представляющая информацию о стеке от основания стека в текущей потоке до вызова регистрации.
-
getMessage() -
Возвращает сообщение для этого экземпляра
LogRecordпосле слияния любых предоставленных пользователем аргументов с сообщением. Если предоставленное пользователем сообщение в вызове регистрации не является строкой, к нему вызываетсяstr()для преобразования в строку. Это позволяет использовать пользовательские классы в качестве сообщений, чей метод__str__может возвращать фактическую строку формата, которая должна использоваться.
Изменено в версии 3.2: Создание
LogRecordбыло сделано более настраиваемым путём предоставления фабрики, которая используется для создания записи. Фабрику можно установить с помощьюgetLogRecordFactory()иsetLogRecordFactory()(см. эту информацию для сигнатуры фабрики).Эта функциональность может быть использована для вставки собственных значений в
LogRecordво время создания. Вы можете использовать следующую схему:old_factory = logging.getLogRecordFactory() def record_factory(*args, **kwargs): record = old_factory(*args, **kwargs) record.custom_attribute = 0xdecafbad return record logging.setLogRecordFactory(record_factory)С этой схемой можно было бы объединить несколько фабрик, и, пока они не перезапишут атрибуты друг друга или не перезапишут стандартные атрибуты, перечисленные выше, не должно быть неожиданностей.
Атрибуты 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 |
| Записанное сообщение, вычисленное как |
module |
| Модуль (имя части |
msecs |
| Миллисекундная часть времени создания |
msg | Вам, скорее всего, не нужно его форматировать самостоятельно. | Строка форматирования, переданная в исходном вызове регистрации. Объединяется с |
name |
| Имя используемого логгера для записи вызова. |
pathname |
| Полный путь к исходному файлу, где был выполнен вызов регистрации (если доступен). |
process |
| Идентификатор процесса (если доступен). |
processName |
| Имя процесса (если доступно). |
relativeCreated |
| Время в миллисекундах создания LogRecord, относительно времени загрузки модуля регистрации. |
stack_info | Вам, скорее всего, не нужно его форматировать самостоятельно. | Информация о стеке кадров (если доступна) с нижнего уровня стека в текущем потоке, включая кадр стека вызова регистрации, который привел к созданию этой записи. |
thread |
| Идентификатор потока (если доступен). |
threadName |
| Имя потока (если доступно). |
Изменено в версии 3.1: Добавлен processName.
Объекты 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. Эти методы делегируют вызов базовому логгеру.
Изменено в версии 3.6: Добавлены атрибут manager и метод _log(), которые делегируют вызовы базовому логгеру и позволяют вкладывать адаптеры.
Безопасность потоков
Модуль ведения журнала предназначен для обеспечения безопасности потоков без необходимости выполнения каких-либо специальных действий со стороны его клиентов. Это достигается с помощью блокировок потоков; существует одна блокировка для сериализации доступа к общим данным модуля, а каждый обработчик также создаёт блокировку для сериализации доступа к его базовому вводу-выводу.
Если вы реализуете обработчики асинхронных сигналов, используя модуль signal, вы можете не иметь возможности использовать ведение журнала внутри таких обработчиков. Это связано с тем, что реализации блокировок в модуле threading не всегда являются рекурсивными, и поэтому не могут вызываться из таких обработчиков сигналов.
Функции уровня модуля
Помимо описанных выше классов, существует ряд функций уровня модуля.
-
logging.getLogger(name=None) -
Возвращает логгер с указанным именем или, если имя равно
None, возвращает логгер, который является корневым логгером иерархии. Если указано, имя обычно представляет собой иерархическое имя, разделенное точкой, например, ‘a’, ‘a.b’ или ‘a.b.c.d’. Выбор этих имен полностью зависит от разработчика, использующего ведение журналов.Все вызовы этой функции с заданным именем возвращают один и тот же экземпляр логгера. Это означает, что экземпляры логгеров никогда не нужно передавать между разными частями приложения.
-
logging.getLoggerClass() -
Возвращает стандартный класс
Loggerили последний класс, переданный вsetLoggerClass(). Эту функцию можно вызывать внутри определения нового класса, чтобы гарантировать, что установка настроенного классаLoggerне отменит уже примененные настройки другим кодом. Например:class MyLogger(logging.getLoggerClass()): # ... override behaviour here
-
logging.getLogRecordFactory() -
Возвращает вызываемый объект, используемый для создания
LogRecord.Новое в версии 3.2: Эта функция предоставлена вместе с
setLogRecordFactory(), чтобы предоставить разработчикам больший контроль над тем, как строитсяLogRecord, представляющий событие ведения журнала.См.
setLogRecordFactory()для получения дополнительной информации о вызове фабрики.
-
logging.debug(msg, *args, **kwargs) -
Записывает сообщение с уровнем
DEBUGв корневой логгер. msg — строка формата сообщения, а args — аргументы, которые объединяются в msg с использованием оператора форматирования строк. (Обратите внимание, что это означает, что вы можете использовать ключевые слова в строке формата вместе с единственным аргументом словаря.)В kwargs проверяются три необязательных ключевых аргумента: exc_info, который, если не оценивается как ложь, вызывает добавление информации об исключении в сообщение ведения журнала. Если предоставлена кортеж исключения (в формате, возвращаемом
sys.exc_info()) или экземпляр исключения, он используется; в противном случае вызываетсяsys.exc_info()для получения информации об исключении.Второй необязательный ключевой аргумент — stack_info, который по умолчанию равен
False. Если истинно, информация о стеке добавляется в сообщение ведения журнала, включая фактический вызов ведения журнала. Обратите внимание, что это не та же информация о стеке, что и при указании exc_info: Первая — это кадры стека снизу до вызова ведения журнала в текущей потоке, а вторая — информация о кадрах стека, которые были размотаны после исключения при поиске обработчиков исключений.Вы можете указать stack_info независимо от exc_info, например, чтобы просто показать, как вы добрались до определенной точки в своем коде, даже когда исключения не были подняты. Кадры стека выводятся после заголовка, который гласит:
Stack (most recent call last):
Это имитирует
Traceback (most recent call last):, используемое при отображении кадров исключения.Третий необязательный ключевой аргумент — extra, который можно использовать для передачи словаря, используемого для заполнения __dict__ созданного для события ведения журнала LogRecord пользовательскими атрибутами. Эти пользовательские атрибуты затем можно использовать по своему усмотрению. Например, их можно включить в записанные сообщения. Например:
FORMAT = '%(asctime)s %(clientip)-15s %(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)выведет что-то вроде:
2006-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().
-
logging.disable(level=CRITICAL) -
Предоставляет переопределяющий уровень level для всех логгеров, имеющий приоритет над собственным уровнем логгера. Когда возникает необходимость временно ограничить вывод журнала по всему приложению, эта функция может быть полезна. Ее действие заключается в отключении всех вызовов ведения журнала с уровнем level и ниже, поэтому, если вы вызываете её со значением INFO, все события INFO и DEBUG будут отброшены, а события WARNING и выше будут обработаны в соответствии с эффективным уровнем логгера. Если
logging.disable(logging.NOTSET)вызывается, это переопределяющий уровень фактически удаляется, так что вывод журнала снова зависит от эффективных уровней отдельных логгеров.Обратите внимание, что если вы определили какой-либо пользовательский уровень ведения журнала выше, чем
CRITICAL(это не рекомендуется), вы не сможете полагаться на значение параметра level по умолчанию, а должны будете явно указать подходящее значение.Изменено в версии 3.7: Параметр level был установлен по умолчанию к уровню
CRITICAL. См. bpo-28524 для получения дополнительной информации об этом изменении.
-
logging.addLevelName(level, levelName) -
Связывает уровень level с текстом levelName во внутреннем словаре, который используется для сопоставления числовых уровней с текстовым представлением, например, когда
Formatterформатирует сообщение. Эта функция также может использоваться для определения собственных уровней. Единственные ограничения заключаются в том, что все используемые уровни должны быть зарегистрированы с помощью этой функции, уровни должны быть положительными целыми числами и они должны увеличиваться по нарастающей степени серьезности.Примечание
Если вы думаете об определении собственных уровней, см. раздел Настраиваемые уровни.
-
logging.getLevelName(level) -
Возвращает текстовое или числовое представление уровня ведения журнала level.
Если level является одним из предопределённых уровней
CRITICAL,ERROR,WARNING,INFOилиDEBUG, то возвращается соответствующая строка. Если вы связали уровни с именами с помощьюaddLevelName(), то возвращается имя, связанное с level. Если передано числовое значение, соответствующее одному из определённых уровней, возвращается соответствующее строковое представление.Параметр level также может принимать строковое представление уровня, например, ‘INFO’. В таких случаях функция возвращает соответствующее числовое значение уровня.
Если не найдено соответствующего числового или строкового значения, возвращается строка ‘Уровень %s’ % level.
Примечание
Уровни — это внутренние целые числа (поскольку они должны сравниваться в логике ведения журнала). Эта функция используется для преобразования между целым числом уровня и именем уровня, отображаемым в отформатированном выводе журнала с помощью спецификатора формата
%(levelname)s(см. Атрибуты записи журнала), и наоборот.Изменено в версии 3.4: В версиях Python, предшествующих 3.4, эта функция также могла принимать текстовый уровень и возвращать соответствующее числовое значение уровня. Это недокументированное поведение считалось ошибкой и было удалено в Python 3.4, но восстановлено в 3.4.2 для сохранения обратной совместимости.
-
logging.makeLogRecord(attrdict) -
Создаёт и возвращает новый экземпляр
LogRecord, атрибуты которого определены в attrdict. Эта функция полезна для извлечения закодированного в двоичный формат словаря атрибутовLogRecord, отправленного по сокету, и его преобразования в экземплярLogRecordна стороне получателя.
-
logging.basicConfig(**kwargs) -
Выполняет базовую настройку системы ведения журнала, создавая
StreamHandlerс предопределённымFormatterи добавляя его в корневой логировщик. Функцииdebug(),info(),warning(),error()иcritical()автоматически вызываютbasicConfig(), если для корневого логировщика не определены обработчики.Эта функция ничего не делает, если у корневого логировщика уже настроены обработчики, если только не указан ключевой аргумент force, значение которого равно
True.Примечание
Эта функция должна вызываться из главного потока перед запуском других потоков. В версиях Python до 2.7.1 и 3.2, если эта функция вызывается из нескольких потоков, существует вероятность (в редких случаях), что обработчик будет добавлен в корневой логировщик более одного раза, что приведёт к неожиданным результатам, таким как дублирование сообщений в журнале.
Поддерживаются следующие ключевые аргументы.
Формат
Описание
filename
Указывает, что должен быть создан FileHandler, используя указанное имя файла, вместо StreamHandler.
filemode
Если указан filename, откройте файл в этом режиме. По умолчанию
'a'.format
Используйте указанную строку формата для обработчика. По умолчанию разделены двоеточиями атрибуты
levelname,nameиmessage.datefmt
Используйте указанный формат даты/времени, как принятый
time.strftime().style
Если указан format, используйте этот стиль для строки формата. Один из
'%','{'или'$'для стиля printf,str.format()илиstring.Templateсоответственно. По умолчанию'%'.level
Установите уровень корневого логировщика на указанный уровень.
stream
Используйте указанный поток для инициализации StreamHandler. Обратите внимание, что этот аргумент несовместим с filename — если оба присутствуют, будет поднято исключение
ValueError.handlers
Если указано, это должен быть итерируемый объект уже созданных обработчиков, которые необходимо добавить в корневой логировщик. Любые обработчики, у которых ещё не задан форматтер, получат предопределённый форматтер, созданный в этой функции. Обратите внимание, что этот аргумент несовместим с filename или stream — если оба присутствуют, будет поднято исключение
ValueError.force
Если этот ключевой аргумент задан как true, все существующие обработчики, прикреплённые к корневому логировщику, будут удалены и закрыты до выполнения настройки, заданной другими аргументами.
encoding
Если этот ключевой аргумент задан вместе с filename, его значение будет использоваться при создании FileHandler и при открытии выходного файла.
errors
Если этот ключевой аргумент задан вместе с filename, его значение будет использоваться при создании FileHandler и при открытии выходного файла. Если не задан, используется значение ‘backslashreplace’. Обратите внимание, что если
Noneзадан, он будет передан как таковой функции:open, что означает, что он будет обработаться так же, как передача ‘errors’.Изменено в версии 3.2: Добавлен аргумент style.
Изменено в версии 3.3: Добавлен аргумент handlers. Добавлены дополнительные проверки для обнаружения ситуаций, когда указаны несовместимые аргументы (например, handlers вместе с stream или filename, или stream вместе с filename).
Изменено в версии 3.8: Добавлен аргумент force.
Изменено в версии 3.9: Добавлены аргументы encoding и errors.
-
logging.shutdown() -
Информирует систему ведения журнала о выполнении упорядоченной остановки путём сброса и закрытия всех обработчиков. Этот вызов следует делать при выходе приложения, и после этого вызова система ведения журнала больше не должна использоваться.
При импорте модуля logging эта функция регистрируется как обработчик выхода (см.
atexit), поэтому обычно нет необходимости делать это вручную.
-
logging.setLoggerClass(klass) -
Указывает системе ведения журнала использовать класс klass при создании экземпляра логировщика. Класс должен определять
__init__()таким образом, чтобы требовался только аргумент имени, и__init__()должен вызыватьLogger.__init__(). Эта функция обычно вызывается до создания любых логировщиков приложениями, которым требуется настроить поведение логировщиков. После этого вызова, как и в любой другой момент, не следует создавать логировщики напрямую с помощью подкласса: продолжайте использовать APIlogging.getLogger()для получения ваших логировщиков.
-
logging.setLogRecordFactory(factory) -
Установите вызываемый объект, используемый для создания
LogRecord.- Параметры
-
factory – вызываемый объект-фабрика, используемый для создания записи журнала.
В версии 3.2: Эта функция предоставлена, наряду с
getLogRecordFactory(), чтобы предоставить разработчикам больший контроль над тем, какLogRecord, представляющая событие регистрации, создается.У фабрики следующий вид сигнатуры:
factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)- name
-
Имя регистратора.
- level
-
Уровень регистрации (числовой).
- fn
-
Полный путь к файлу, где был сделан вызов регистрации.
- lno
-
Номер строки в файле, где был сделан вызов регистрации.
- msg
-
Сообщение регистрации.
- args
-
Аргументы для сообщения регистрации.
- exc_info
-
Кортеж исключения или
None. - func
-
Имя функции или метода, вызвавшего вызов регистрации.
- sinfo
-
Стек отладки, такой как предоставляется
traceback.print_stack(), показывающий иерархию вызовов. - kwargs
-
Дополнительные ключевые аргументы.
Атрибуты уровня модуля
-
logging.lastResort -
«Обработчик последней надежды» доступен через этот атрибут. Это
StreamHandler, который записывает вsys.stderrс уровнемWARNING, и используется для обработки событий регистрации при отсутствии какой-либо конфигурации регистрации. Конечный результат — просто вывод сообщения вsys.stderr. Это заменяет предыдущее сообщение об ошибке, которое гласит, что «не было найдено обработчиков для регистратора XYZ». Если вам по какой-либо причине нужен предыдущий результат,lastResortможно установить наNone.В версии 3.2.
Интеграция с модулем warnings
Функция captureWarnings() может быть использована для интеграции logging с модулем warnings.
-
logging.captureWarnings(capture) -
Эта функция используется для включения и отключения захвата предупреждений системой регистрации.
Если capture равно
True, предупреждения, выпущенные модулемwarnings, будут перенаправлены в систему регистрации. В частности, предупреждение будет отформатировано с помощьюwarnings.formatwarning()и полученная строка будет записана в регистратор с именем'py.warnings'с уровнем серьезностиWARNING.Если capture равно
False, перенаправление предупреждений в систему регистрации прекратится, и предупреждения будут перенаправлены в их исходные места назначения (т.е. те, которые действовали до вызоваcaptureWarnings(True)).
См. также
-
Modulelogging.config -
API конфигурации для модуля регистрации.
-
Modulelogging.handlers -
Полезные обработчики, включенные в модуль регистрации.
- PEP 282 - Система регистрации
-
Предложение, которое описывало эту функцию для включения в стандартную библиотеку Python.
- Исходный пакет Python logging
-
Это исходный код пакета
logging. Версия пакета, доступная с этого сайта, подходит для использования с Python 1.5.2, 2.1.x и 2.2.x, которые не включают пакетloggingв стандартную библиотеку.
© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/library/logging.html