logging
— Логирование для Python
Модуль определяет функции и классы, которые реализуют гибкую систему логирования событий для приложений и библиотек.
Ключевым преимуществом наличия API журналирования, является то, что любые Python модули могут участвовать в логировании, поэтому журнал вашего приложения может включать собственные сообщения, интегрированные с сообщениями от сторонних модулей.
Модуль предоставляет большую функциональность и гибкость, а также распространяется в составе стандартной библиотеки. Если вы не знакомы с логгированием, лучший способ разобраться с ним — это просмотреть руководства (см. ссылки справа).
Основные классы, определенные модулем, вместе с их методами перечислены ниже.
- Логгеры предоставляют интерфейс, который может напрямую использоваться кодом приложения.
- Обработчики отправляют записи журнала (созданные логгерами) в соответствующее место назначения.
- Фильтры предоставляют более детальное средство для определения, какие записи журнала нужно выводить.
- Средства форматирования определяют структуру записей журнала в окончательном выводе.
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
Если у атрибута установлено истинное значение, события, зарегистрированные в этом логгере, будут переданы обработчикам логгеров более высокого уровня (предков) в дополнение к любым обработчикам, присоединенным к данному логгеру. Сообщения передаются непосредственно обработчикам логгеров предков — ни уровень, ни фильтры рассматриваемых логгеров предков не учитываются.
Если принимает значение false, сообщения журнала не передаются обработчикам логирования предков.
Конструктор устанавливает для данного атрибута значение
True
.Примечание
Если прикрепить обработчик к логгеру и к одному или нескольким его предков, он может генерировать одну и ту же запись несколько раз. В общем, не нужно прикреплять обработчик к более чем одному логгеру — если прикрепить его к соответствующему логгеру, который находится наверху в иерархии логгера, тогда он будет видеть все события, зарегистрированные всеми дочерними логгерами при условии, что для их параметра propagate установлено значение
True
. Общий сценарий состоит в том, чтобы прикрепить обработчики только к корневому логгеру и разрешить распространению заботится обо всех остальных.
-
setLevel
(level) Устанавливает порог для данного логгера равным level. Сообщения журнала, которые менее серьезны, чем level, будут игнорироваться; сообщения журнала, с уровнем серьезности level или выше, будут выдаваться обработчиком или обработчиками, обслуживающими этим логгером, если для уровня обработчика не задан более высокий уровень серьезности, чем level.
При создании логгера устанавливается уровень
NOTSET
(что приводит к тому, что все сообщения обрабатываются, когда логгер является корневым логгером, или делегируются родительскому объекту, когда логгер не является корневым логгером). Обратите внимание, что корневой логгер создаётся с уровнемWARNING
.Термин «делегирование родителю» означает, что если у логгера уровень NOTSET, цепочка его логгеров предков просматривается до тех пор, пока не будет найден предок с уровнем, отличным от NOTSET, или не будет достигнут корень.
Если предок обнаружен с уровнем, отличным от NOTSET, то уровень этого предка рассматривается как эффективный уровень логгера, с которого начался поиск предка, и используется для определения того, как обрабатывается событие логирования.
Если корень достигнут, и у него уровень NOTSET, то все сообщения будут обработаны. В противном случае уровень корня будет использоваться как эффективный уровень.
Список уровней см. в Уровни ведения журнала.
Изменено в версии 3.2: Параметр level теперь принимает строковое представление, такое как «INFO», в качестве альтернативы целочисленным константам, таким как
INFO
. Обратите внимание, однако, что уровни внутри хранятся как целые числа, а такие методы, как, например,getEffectiveLevel()
иisEnabledFor()
будут возвращать/ожидать передачи целых чисел.
-
isEnabledFor
(level) Указывает, будет ли обработано данным логгером сообщение с серьезностью 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 не считается ложным, то приводит к добавлению информации об исключении в сообщение журнала. Если предоставляется кортеж исключения (в формате, возвращаемом
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):
, который используется при отображении фреймов исключений.Третий необязательный ключевой аргумент — stacklevel, значение по умолчанию —
1
. Если больше 1, соответствующее количество фреймов стека пропускается при вычислении номера строки и имени функции, заданных вLogRecord
, созданном для события логирования. Его можно использовать в помощниках ведения журнала, чтобы записанные имя функции, имя файла и номер строки не были информацией для вспомогательной функции/метода, а скорее были её вызывающей стороной. Имя этого параметра отражает эквивалентное имя в модулеwarnings
.Четвертым ключевым аргументом является extra, который можно использовать для передачи словаря, используемый для заполнения __dict__
LogRecord
, созданного для события логирования, определяемыми пользователем атрибутами. Затем эти настраиваемые атрибуты можно использовать по своему усмотрению. Например, они могут быть включены в логгируемые сообщения. Например:FORMAT = '%(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)
напечатал бы что-то вроде
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
, если запись должна быть обработана. Фильтры просматриваются по очереди, пока один из них не вернёт ложное значение. Если ни один из них не вернёт ложное значение, запись будет обработана (передана обработчикам). Если возвращается ложное значение, дальнейшая обработка записи не происходит.
-
addHandler
(hdlr) Добавляет указанный обработчик hdlr к логгеру.
-
removeHandler
(hdlr) Удаляет указанный обработчик hdlr из логгера.
-
findCaller
(stack_info=False, stacklevel=1) Находит исходник имени файла вызывающего и номер строки. Возвращает имя файла, номер строки, имя функции и информацию о стеке в виде четырёхэлементного кортежа. Возвращается
None
из стека, если stack_info неTrue
.Параметр stacklevel передаётся из кода, вызывающего
debug()
и другие API. Если больше 1, избыток используется для пропуска фреймов стека перед определением возвращаемых значений. Как правило, это будет полезно при вызове API логгера из кода помощника/оболочки, чтобы информация в журнале событий относилась не к коду помощника/оболочки, а к коду, который его вызывает.
-
handle
(record) Обрабатывает запись, передавая её всем обработчикам, связанным с логгером и его предками (до тех пор, пока не будет найдено ложное значение propagate). Метод используется для неотобранных записей, полученных из сокета, а также для записей, созданных локально. Фильтрация на уровне логгера применяется с использованием
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: Логгеры теперь можно пиклить (pickled) и анпиклить (unpickled).
-
Уровни ведения журнала
Числовые значения уровней журналирования приведены в следующей таблице. В первую очередь они будут интересны тем, кому нужно определить свои собственные уровни и хотите, чтобы у них были определенные значения относительно предопределенных уровней. Если вы определяете уровень с тем же числовым значением, он перезаписывает предопределенное значение; предопределенное имя теряется.
Уровень | Числовое значение |
---|---|
CRITICAL |
50 |
ERROR |
40 |
WARNING |
30 |
INFO |
20 |
DEBUG |
10 |
NOTSET |
0 |
Объекты-обработчики
У обработчиков есть следующие атрибуты и методы. Обратите внимание, что
Handler
никогда не создаётся напрямую; данный класс выступает в качестве
основы для более полезных подклассов. Однако метод __init__()
в
подклассах должен вызывать Handler.__init__()
.
-
class
logging.
Handler
-
__init__
(level=NOTSET) Инициализирует экземпляр
Handler
, устанавливая его уровень, устанавливая для списка фильтров пустой список и создавая блокировку (с использованиемcreateLock()
) для сериализации доступа к механизму ввода-вывода.
-
createLock
() Инициализирует блокировку потока, используемую для сериализации доступа к базовым функциям ввода-вывода, которые могут не быть потокобезопасны.
-
acquire
() Получает блокировку потока, созданную с помощью
createLock()
.
-
release
() Освобождает блокировку потока, полученной с помощью
acquire()
.
-
setLevel
(level) Устанавливает порог для обработчика равным level. Сообщения журнала, которые менее серьезны, чем level, будут игнорироваться. Когда создается обработчик, устанавливается уровень
NOTSET
(что вызывает обработку всех сообщений).Список уровней см. в Уровни ведения журнала.
Изменено в версии 3.2: Параметр level теперь принимает строковое представление уровня, такое как INFO, в качестве альтернативы целочисленным константам, таким как
INFO
.
-
setFormatter
(fmt) Устанавливает
Formatter
для обработчика на fmt.
-
addFilter
(filter) Добавляет указанный фильтр filter к обработчику.
-
removeFilter
(filter) Удаляет указанный фильтр filter из обработчика.
-
filter
(record) Применить фильтры обработчика к записи и вернуть
True
, если запись должна быть обработана. Фильтры просматриваются по очереди, пока один из них не вернёт ложное значение. Если ни один из них не вернёт ложное значение, запись будет отправлена. Если один из них возвращает ложное значение, обработчик не отправит запись.
-
flush
() Убедиться, что весь вывод журнала сброшен. Данная версия ничего не делает и предназначена для реализации подклассами.
-
close
() Очистить все ресурсы, используемые обработчиком. Данная версия не выводит данные, но удаляет обработчик из внутреннего списка обработчиков, который закрывается при вызове
shutdown()
. Подклассы должны гарантировать, что это вызывается из переопределенных методовclose()
.
-
handle
(record) Условно генерирует указанную запись журнала, в зависимости от фильтров, которые могли быть добавлены в обработчик. Оборачивает фактическое излучение записи с получением/снятием блокировки потока ввода-вывода.
-
handleError
(record) Метод следует вызывать из обработчиков при возникновении исключения во время вызова
emit()
. Если атрибутraiseExceptions
уровня модуля равенFalse
, исключения автоматически игнорируются. Это то, что больше всего требуется для системы журналирования — большинство пользователей не будут заботиться об ошибках в системе журналов, их больше интересуют ошибки приложений. Однако вы можете заменить его специальным обработчиком, если хотите. Указанная запись — это та, которая обрабатывалась, когда произошло исключение. (Значение по умолчаниюraiseExceptions
—True
, т. к. это более полезно во время разработки).
-
format
(record) Выполнить форматирование для записи — если форматтер установлен, использовать его. В противном случае использовать форматтер по умолчанию для модуля.
-
emit
(record) Сделать всё возможное, чтобы фактически зарегистрировать указанную запись в журнале. Версия предназначена для реализации с помощью подклассов и поэтому вызывает
NotImplementedError
.
-
Для получения списка стандартных обработчиков см. в logging.handlers
.
Formatter объекты
У объектов Formatter
есть следующие атрибуты и методы. Они отвечают за
преобразование LogRecord
в (обычно) строку, которая может
интерпретироваться как человеком, так и внешней системой. База Formatter
позволяет указать строку форматирования. Если ничего не указано, используется
значение по умолчанию '%(message)s'
, которое просто включает сообщение в
вызов журнала. Чтобы в форматированном выводе отображалась дополнительная
информация (например, временная метка), продолжайте чтение.
Formatter может быть инициализирован строкой формата, которая использует
сведения об атрибутах LogRecord
— например, значение по умолчанию,
упомянутое выше, с использованием того факта, что сообщение и аргументы
пользователя предварительно отформатированы в атрибуте message
LogRecord
. Строка формата содержит стандартные ключи
сопоставления %-стиля Python. См. раздел Форматирование строк в стиле printf для
получения дополнительной информации о форматировании строк.
Полезные ключи сопоставления в LogRecord
приведены в разделе
Атрибуты LogRecord.
-
class
logging.
Formatter
(fmt=None, datefmt=None, style='%') Возвращает новый экземпляр класса
Formatter
. Экземпляр инициализируется строкой формата для сообщения в целом, а также строкой формата для части сообщения, относящейся к дате/времени. Если fmt не указан, используется'%(message)s'
. Если datefmt не указан, используется формат, рассмотренный в документацииformatTime()
.Параметр style может быть одним из «%», «{» или «$» и определяет, как строка формата будет объединена с её данными: с использованием одного из %-форматирования,
str.format()
илиstring.Template
. См. Использование определенных стилей форматирования во всём приложении для получения дополнительной информации об использовании {- и $ -форматировании для сообщений журнала.Изменено в версии 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()
. Чтобы изменить его для всех форматеров, например, если вы хотите, чтобы все время логирования отображалось в 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()
, но с удаленной последней новой строкой) как строку. Реализация по умолчанию просто возвращает входное значение.
-
Filter объекты
Фильтры
могут использоваться Обработчиками
и Логгерами
для более сложной
фильтрации, чем это предусмотрено уровнями. Базовый класс фильтра разрешает
только события, которые находятся ниже определенной точки в иерархии
логгера. Например, фильтр, инициализированный с помощью «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) Должна ли регистрироваться указанная запись? Возвращает ноль, если нет, ненулевое значение, если да. Если это будет сочтено целесообразным, запись может быть изменена этим методом на месте.
-
Обратите внимание, что фильтры, прикрепленные к обработчикам, просматриваются
до того, как событие будет отправлено обработчиком, тогда как фильтры,
прикрепленные к логгерам, проверяются всякий раз, когда
логируется событие (с использованием debug()
, info()
и т. д.),
перед отправкой события обработчикам. Это означает, что события, которые были
сгенерированы потомками логгеров, не будут отфильтрованы настройкой
фильтра логгера, если только фильтр не был применён к этим потомкам
логгеров.
На самом деле вам не нужно создавать подкласс Filter
: вы можете передать
любой экземпляр, у которого есть метод filter
с той же семантикой.
Изменено в версии 3.2: Вам не нужно создавать специализированные классы Filter
или использовать
другие классы с методом filter
: вы можете использовать функцию (или
другой вызываемый объект) в качестве фильтра. Логика фильтрации проверяет,
есть ли объекта фильтра атрибут filter
: если он есть, предполагается,
что это Filter
, и вызывается его метод filter()
. В
противном случае он считается вызываемым и вызывается с записью в качестве
единственного параметра. Возвращаемое значение должно соответствовать
возвращаемому filter()
.
Хотя фильтры используются в основном для фильтрации записей на основе более
сложных критериев, чем уровни, они могут видеть каждую
обрабатываемую обработчиком или логгером запись, к которой они прикреплены: это
может быть полезно, если вам нужно посчитать количество
обработанных записей определенным логгером или обработчиком, либо
добавлялись, изменялись или удалялись атрибуты в обрабатываемом
LogRecord
. Очевидно, что изменение 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
записи.Параметры: - name – Имя логгера, используемого для логирования события, представленного LogRecord. Обратите внимание, что у имени всегда будет данное значение, даже если оно отправлено обработчиком, прикреплённого к другому (предок) логгеру.
- level – Числовой уровень события логирования (один из DEBUG, INFO и т. д.)
Обратите внимание, что он преобразуется в
два атрибута файла LogRecord:
levelno
для числового значения иlevelname
для соответствующее название уровня. - pathname – Полный путь к исходному файлу, в котором был выполнен вызов журналирования.
- lneno – Номер строки в исходном файле, в котором был сделан вызов журналирования.
- msg – Сообщение с описанием события, возможно, форматная строка с заполнителями для переменных данных.
- args – Переменные данные, которые нужно объединить с аргументом msg для получения описания события.
- exc_info – Кортеж исключения с текущей информацией об исключении
или
None
, если информация об исключении недоступна. - func – Имя функции или метода, из которого был вызван вызов журналирования.
- 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 | Вам не нужно форматировать его самостоятельно. | Кортеж аргументов слитый в msg , чтобы
произвести message или словарь, значения
которого используются для слияния (когда есть
только один аргумент, и это словарь). |
asctime | %(asctime)s |
Читаемое человеком время создания
LogRecord . По умолчанию выглядит как
„2003-07-08 16:49: 45,896“ (числа после запятой
являются миллисекундной частью
времени). |
created | %(created)f |
Время, когда LogRecord был создан
(как возвращенный time.time() ). |
exc_info | Вам не нужно форматировать его самостоятельно. | Кортеж исключения (в духе sys.exc_info ) или,
если не произошло исключения None . |
filename | %(filename)s |
Filename части pathname . |
funcName | %(funcName)s |
Имя функции, содержащей вызов логирования. |
levelname | %(levelname)s |
Текстовый уровень логирования для сообщения
('DEBUG' , 'INFO' , 'WARNING' ,
'ERROR' , 'CRITICAL' ). |
levelno | %(levelno)s |
Числовой уровень логирования для сообщения
(DEBUG , INFO ,
WARNING , ERROR ,
CRITICAL ). |
lineno | %(lineno)d |
Номер строки исходника, из которой был сделан вызов логирования (если доступен). |
message | %(message)s |
Зарегистрированное сообщение, вычисленное как
msg % args . Параметр устанавливается
при вызове функции «Formatter.format() ». |
module | %(module)s |
Модуль (часть имени filename ). |
msecs | %(msecs)d |
|
msg | Вам не нужно форматировать его самостоятельно. | Форматная строка переданная в исходном вызове
логирования. Слитый с args , чтобы произвести
message или произвольный объект (см.
Использование произвольных объектов в качестве сообщений). |
name | %(name)s |
Имя логгера используемого для логирования вызова. |
pathname | %(pathname)s |
Полное имя пути к исходному файлу, в котором был выполнен вызов логирования (если доступно). |
process | %(process)d |
ID процесса (если доступен). |
processName | %(processName)s |
Имя процесса (если доступен). |
relativeCreated | %(relativeCreated)d |
Время в миллисекундах при создании LogRecord относительно времени загрузки модуля logging. |
stack_info | Вам не нужно форматировать это самостоятельно. | Информация о стековом фрейме (если таковая имеется) из нижней части стека в текущем потоке, вплоть до стекового фрейма вызова логирования, который привёл к созданию этой записи. |
thread | %(thread)d |
ID потока (если доступен). |
threadName | %(threadName)s |
Имя потока (если доступно). |
Изменено в версии 3.1: Был добавлен processName.
Объекты LoggerAdapter
Экземпляры LoggerAdapter
используются для удобной передачи контекстной
информации при вызове логирования. Пример использования см. в разделе
добавление контекстной информации в выходные данные журнала.
-
class
logging.
LoggerAdapter
(logger, extra) Возвращает экземпляр
LoggerAdapter
, инициализированный базовым экземпляромLogger
и dict-подобным объектом.-
process
(msg, kwargs) Изменяет сообщение и/или ключевые аргументы, переданные вызову логирования, чтобы вставить контекстную информацию. Реализация принимает объект, переданный как extra, в конструктор и добавляет его в kwargs с помощью ключа extra. Возвращаемое значение — кортеж (msg, kwargs), у которого есть (возможно, измененные) версии переданных аргументов.
-
В дополнение к вышесказанному, LoggerAdapter
поддерживает следующие
методы: Logger
: debug()
, info()
,
warning()
, error()
, exception()
,
critical()
, log()
, isEnabledFor()
,
getEffectiveLevel()
и У данных методов
те же сигнатуры, что и их аналоги в :class:`Logger()
, поэтому вы можете
использовать оба типа экземпляров как взаимозаменяемые.
Изменено в версии 3.2: В LoggerAdapter
добавлены методы isEnabledFor()
,
getEffectiveLevel()
, setLevel()
и
hasHandlers()
. Методы делегируются базовому логгеру.
Безопасность потоков
Модуль logging является потокобезопасным, поэтому его клиенты не должны выполнять каких-либо специальных действий. Это достигается с помощью блокировки потоков; существует одна блокировка для сериализации доступа к общим данным модуля, и каждый обработчик также создаёт блокировку для сериализации доступа к своему базовому вводу-выводу.
Если вы реализуете асинхронные обработчики сигналов с помощью модуля
signal
, возможно, вы не сможете использовать логгирование из таких
обработчиков. Это связано с тем, что реализации блокировки в модуле
threading
не всегда реентерабельны, и поэтому не могут быть вызваны из
таких обработчиков сигналов.
Функции уровня модуля
В дополнение к классам, описанным выше, существует ряд функций уровня модуля.
-
logging.
getLogger
(name=None) Возвращает логгер с указанным именем или, если имя
None
, вернуть логгер, который является корневым логгером иерархии. Если указано, имя обычно представляет собой иерархическое имя, разделенное точками, например „a“, „a.b“ или „a.b.c.d“. Выбор этих имён полностью зависит от разработчика, использующего logging.Все вызовы функции с заданным именем возвращают один и тот же экземпляр логгера. Это означает, что экземпляры логгера никогда не нужно передавать между разными частями приложения.
-
logging.
getLoggerClass
() Возвращает либо стандартный класс
Logger
, либо последний класс, переданный вsetLoggerClass()
. Функцию можно вызвать из определения нового класса, чтобы гарантировать, что установка настроенного классаLogger
не приведет к отмене настроек, уже примененных другим кодом. Например:class MyLogger(logging.getLoggerClass()): # ... переопределить здесь поведение
-
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)-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)
напечатал бы что-то вроде:
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
Ключи в словаре, переданном в extra, не должны конфликтовать с ключами, используемыми системой логирования. (См. документацию
Formatter
для получения дополнительной информации о том, какие ключи используются системой logging.)Если вы решите использовать эти атрибуты в логгируемых сообщениях, вам нужно проявить некоторую осторожность. В приведенном выше примере, например,
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
(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. Если уровень является одним из предопределенных уровней
CRITICAL
,ERROR
,WARNING
,INFO
илиDEBUG
, вы получаете соответствующую строку. Если вы связали уровни с именами с помощьюaddLevelName()
, то возвращается имя, связанное с level. Если передается числовое значение, соответствующее одному из определенных уровней, возвращается соответствующее строковое представление. В противном случае возвращается строка «Level %s» % level.Примечание
Уровни внутренне целочисленные (т. к. их нужно сравнивать в логике логирования). Функция используется для преобразования между целочисленным уровнем и именем уровня, отображаемым в форматированных выводах журнала, с помощью спецификатора формата
%(levelname)s
(см. Атрибуты LogRecord).Изменено в версии 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 Использовать указанную форматную строку для обработчика. datefmt Использовать указанный формат даты и времени, принятый time.strftime()
.style Если задан параметр format, использовать этот стиль для форматной строки. Один из '%'
,'{'
или'$'
для printf-стиль,str.format()
илиstring.Template
соответственно. По умолчанию используется значение'%'
.level Установить уровень корневого логгера на указанный уровень. stream Использовать указанный поток для инициализации StreamHandler. Обратите внимание, что этот аргумент несовместим с filename — если присутствуют оба, вызывается ValueError
.handlers Если указан, он должен быть итератором уже созданных обработчиков для добавления к корневому логгеру. Любые обработчики, которым не установлен форматтер, назначается форматтер по умолчанию, созданное в этой функции. Обратите внимание, что этот аргумент несовместим с filename или stream — если они присутствуют, вызывается ValueError
.force Если данный ключевой аргумент указан как true, все существующие обработчики, присоединенные к корневому логгеру, удаляются и закрываются перед выполнением конфигурации, указанной другими аргументами. Изменено в версии 3.2: Был добавлен аргумент style.
Изменено в версии 3.3: Добавлен аргумент handlers. Были добавлены дополнительные проверки для выявления ситуаций, в которых указаны несовместимые аргументы (например, handlers вместе с stream или filename или stream вместе с filename).
Изменено в версии 3.8: Был добавлен аргумент force.
-
logging.
shutdown
() Информирует систему логирования о необходимости корректного завершения работы путём продувки и закрытия всех обработчиков. Должна вызываться при выходе из приложения, и после её вызова нельзя использовать logging систему.
Когда модуль logging импортируется, он регистрирует эту функцию как обработчик выхода (см.
atexit
), поэтому обычно нет необходимости делать это вручную.
-
logging.
setLoggerClass
(klass) Указывает logging системе использовать класс klass при создании экземпляра логгера. Класс должен определять
__init__()
таким образом, чтобы требовался только аргумент имени, а__init__()
должен вызыватьLogger.__init__()
. Функция обычно вызывается до того, как какие-либо логгеры будут созданы приложениями, которым необходимо использовать настраиваемое поведение логгера. После этого вызова, как и в любое другое время, не создавайте экземпляры регистраторов непосредственно с помощью подкласса: продолжайте использоватьlogging.getLogger()
API для получения ваших регистраторов.
-
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: Имя функции или метода, которая вызвала logging. 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)
).
См.также
- Модуль
logging.config
- API конфигурации для модуля logging.
- Модуль
logging.handlers
- Полезные обработчики, включенные в модуль logging.
- PEP 282 — Система логирования
- Предложение, рассказывающее о функции для включения в стандартную Python библиотеку.
- Оригинальный пакет logging Python
- Исходный код пакета
logging
. Версия пакета, доступная на этом сайте, подходит для использования с Python 1.5.2, 2.1.x и 2.2.x, которые не включают пакетlogging
в стандартную библиотеку.