logging — Система ведения журналов для Python
Исходный код: Lib/logging/__init__.py
Этот модуль определяет функции и классы, которые реализуют гибкую систему ведения событий журналов для приложений и библиотек.
Ключевое преимущество использования API ведения журнала, предоставляемого модулем стандартной библиотеки, заключается в том, что все модули Python могут участвовать в ведении журнала, поэтому ваш журнальный файл приложения может содержать ваши собственные сообщения, интегрированные с сообщениями модулей сторонних производителей.
Модуль предоставляет множество функциональных возможностей и гибкости. Если вы не знакомы с ведением журналов, лучший способ разобраться в нём — ознакомиться с учебниками (см. ссылки справа).
Основные классы, определенные модулем, вместе со своими функциями, перечислены ниже.
- Логгеры предоставляют интерфейс, который напрямую использует код приложения.
- Обработчики отправляют записи журнала (созданные логгерами) в соответствующее место назначения.
- Фильтры обеспечивают более тонкую возможность определения записей журнала, которые необходимо выводить.
- Форматировщики определяют макет записей журнала в конечном выводе.
1. Объекты логгера
Логгеры имеют следующие атрибуты и методы. Обратите внимание, что логгеры никогда не создаются напрямую, но всегда через функцию уровня модуля logging.getLogger(name). Несколько вызовов getLogger() с одинаковым именем всегда возвращают ссылку на тот же объект Logger.
Имя логгера потенциально является значением с разделителями в виде точки, например foo.bar.baz (хотя оно также может быть просто foo, например). Логгеры, которые находятся ниже в иерархическом списке, являются дочерними логгерами логгеров, расположенных выше в списке. Например, при наличии логгера с именем foo, логгеры с именами foo.bar, foo.bar.baz, и foo.bam являются потомками foo. Иерархия имён логгеров аналогична иерархии пакетов Python, и идентична ей, если вы организуете свои логгеры по модулям, используя рекомендуемую конструкцию logging.getLogger(__name__). Это потому, что в модуле __name__ — это имя модуля в пространстве имён пакета Python.
-
class logging.Logger
-
Logger.propagate -
Если это значение равно true, события, записанные в этот логгер, будут переданы обработчикам логгеров более высокого уровня (предкам), помимо любых обработчиков, подключенных к этому логгеру. Сообщения передаются напрямую обработчикам логгеров-предков — ни уровень, ни фильтры предков логгеров не учитываются.
Если это значение равно false, сообщения журнала не передаются обработчикам логгеров-предков.
Конструктор устанавливает этот атрибут в
True.Примечание
Если вы подключите обработчик к логгеру и одному или нескольким его предкам, он может выводить одну и ту же запись несколько раз. В общем случае, вам не нужно подключать обработчик к более чем одному логгеру — если вы подключите его к соответствующему логгеру, который находится выше в иерархии логгеров, он будет видеть все события, записанные всеми дочерними логгерами, при условии, что их параметр распространения установлен на
True. Общий случай — подключение обработчиков только к корневому логгеру и предоставление распространения для остальной части.
-
Logger.setLevel(lvl) -
Устанавливает порог для этого логгера в lvl. Сообщения журнала, которые менее серьезны, чем lvl, будут игнорироваться. При создании логгера уровень устанавливается в
NOTSET(что вызывает обработку всех сообщений, когда логгер является корневым логгером, или делегирование родителю, когда логгер — это не корневой логгер). Обратите внимание, что корневой логгер создается с уровнемWARNING.Термин «делегирование родителю» означает, что если у логгера уровень NOTSET, его цепочка предков логгеров просматривается до тех пор, пока не будет найден предок с уровнем, отличным от NOTSET, или не будет достигнут корень.
Если предок с уровнем, отличным от NOTSET, найден, уровень этого предка рассматривается как эффективный уровень логгера, с которого начался поиск предка, и используется для определения того, как обрабатывается событие ведения журнала.
Если достигнут корень, и у него уровень NOTSET, то все сообщения будут обработаны. В противном случае уровень корня будет использоваться как эффективный уровень.
См. Уровни ведения журналов для списка уровней.
Изменено в версии 3.2: Параметр lvl теперь принимает строковое представление уровня, например «INFO», как альтернативу целочисленным константам, таким как
INFO. Однако обратите внимание, что уровни внутренне хранятся как целые числа, и такие методы, как, например,getEffectiveLevel()иisEnabledFor(), будут возвращать/ожидать целые числа.
-
Logger.isEnabledFor(lvl) -
Указывает, будет ли сообщение с уровнем серьезности lvl обработано этим логгером. Этот метод сначала проверяет уровень модуля, установленный
logging.disable(lvl), а затем эффективный уровень логгера, определенный с помощьюgetEffectiveLevel().
-
Logger.getEffectiveLevel() -
Указывает эффективный уровень для этого логгера. Если значение, отличное от
NOTSET, было установлено с помощьюsetLevel(), оно возвращается. В противном случае иерархия просматривается в направлении к корню, пока не будет найдено значение, отличное отNOTSET, и это значение возвращается. Возвращаемое значение является целым числом, как правило, одним изlogging.DEBUG,logging.INFOи т. д.
-
Logger.getChild(suffix) -
Возвращает логгер, который является потомком этого логгера, как определено суффиксом. Таким образом,
logging.getLogger('abc').getChild('def.ghi')вернёт тот же логгер, что иlogging.getLogger('abc.def.ghi'). Это удобный метод, полезный, когда родительский логгер назван, например,__name__вместо литеральной строки.Новое в версии 3.2.
-
Logger.debug(msg, *args, **kwargs) -
Записывает сообщение с уровнем
DEBUGв этом логгере. Строка msg — это строка формата сообщения, а args — это аргументы, которые объединяются в msg с помощью оператора форматирования строк. (Обратите внимание, что это означает, что вы можете использовать ключевые слова в строке формата вместе с единственным аргументом-словарём.)В kwargs проверяются три ключевых аргумента: exc_info, stack_info и extra.
Если exc_info не оценивается как ложь, это приводит к добавлению информации об исключении в сообщение логирования. Если предоставлена кортеж исключения (в формате, возвращаемом
sys.exc_info()) или экземпляр исключения, он используется; в противном случае, вызываетсяsys.exc_info()для получения информации об исключении.Вторым необязательным ключевым аргументом является stack_info, который по умолчанию равен
False. Если значение истинно, в сообщение логирования добавляется информация о стеке, включая фактический вызов логирования. Обратите внимание, что это не та же информация о стеке, что и та, которая отображается с помощью указания 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'} 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 теперь может принимать экземпляры исключений.
-
Logger.info(msg, *args, **kwargs) -
Записывает сообщение с уровнем
INFOв этом логгере. Аргументы интерпретируются аналогичноdebug().
-
Logger.warning(msg, *args, **kwargs) -
Записывает сообщение с уровнем
WARNINGв этом логгере. Аргументы интерпретируются аналогичноdebug().Примечание
Существует устаревший метод
warn, который функционально идентиченwarning. Посколькуwarnустарел, не используйте его - используйтеwarningвместо него.
-
Logger.error(msg, *args, **kwargs) -
Записывает сообщение с уровнем
ERRORв этом логгере. Аргументы интерпретируются аналогичноdebug().
-
Logger.critical(msg, *args, **kwargs) -
Записывает сообщение с уровнем
CRITICALв этом логгере. Аргументы интерпретируются аналогичноdebug().
-
Logger.log(lvl, msg, *args, **kwargs) -
Записывает сообщение с целочисленным уровнем lvl в этом логгере. Остальные аргументы интерпретируются аналогично
debug().
-
Logger.exception(msg, *args, **kwargs) -
Записывает сообщение с уровнем
ERRORв этом логгере. Аргументы интерпретируются аналогичноdebug(). Информация об исключении добавляется в сообщение логирования. Этот метод должен вызываться только из обработчика исключений.
-
Logger.addFilter(filt) -
Добавляет указанный фильтр filt в этот логгер.
-
Logger.removeFilter(filt) -
Удаляет указанный фильтр filt из этого логгера.
-
Logger.filter(record) -
Применяет фильтры этого логгера к записи и возвращает истинное значение, если запись должна быть обработана. Фильтры проверяются поочерёдно, пока один из них не вернёт ложное значение. Если ни один из них не вернёт ложное значение, запись будет обработана (передана обработчикам). Если один вернёт ложное значение, дальнейшая обработка записи не происходит.
-
Logger.addHandler(hdlr) -
Добавляет указанный обработчик hdlr в этот логгер.
-
Logger.removeHandler(hdlr) -
Удаляет указанный обработчик hdlr из этого логгера.
-
Logger.findCaller(stack_info=False) -
Находит имя файла источника вызывающего объекта и номер строки. Возвращает имя файла, номер строки, имя функции и информацию о стеке в виде кортежа из 4 элементов. Информация о стеке возвращается как
None, если stack_info неTrue.
-
Logger.handle(record) -
Обрабатывает запись, передавая её всем обработчикам, связанным с этим логгером и его предками (до тех пор, пока не будет найдено ложное значение propagate). Этот метод используется для распакованных записей, полученных по сокету, а также для тех, которые созданы локально. Фильтрация на уровне логгера применяется с помощью
filter().
-
Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None) -
Это фабричный метод, который может быть переопределён в подклассах для создания специализированных экземпляров
LogRecord.
-
Logger.hasHandlers() -
Проверяет, есть ли у этого логгера какие-либо обработчики. Это делается путём поиска обработчиков в этом логгере и его родителях в иерархии логгеров. Возвращает
True, если был найден обработчик, иначеFalse. Поиск по иерархии прекращается, когда встречается логгер с атрибутом «propagate», установленным в ложь - это будет последний логгер, который проверяется на наличие обработчиков.Добавлено в версии 3.2.
2. Уровни логирования
Числовые значения уровней логирования приведены в следующей таблице. Они в основном интересны, если вы хотите определить свои собственные уровни и им нужны определённые значения по отношению к предопределённым уровням. Если вы определяете уровень с тем же числовым значением, он перезаписывает предопределённое значение; имя предопределённого уровня теряется.
| Уровень | Числовое значение |
|---|---|
CRITICAL | 50 |
ERROR | 40 |
WARNING | 30 |
INFO | 20 |
DEBUG | 10 |
NOTSET | 0 |
3. Объекты обработчиков
Обработчики имеют следующие атрибуты и методы. Обратите внимание, что Handler никогда не создаётся напрямую; этот класс служит основой для более полезных подклассов. Однако метод __init__() в подклассах должен вызывать Handler.__init__().
-
Handler.__init__(level=NOTSET) -
Инициализирует экземпляр
Handlerпутём установки его уровня, установки списка фильтров в пустой список и создания блокировки (с помощьюcreateLock()) для сериализации доступа к механизму ввода-вывода.
-
Handler.createLock() -
Инициализирует блокировку потока, которая может использоваться для сериализации доступа к базовым функциям ввода-вывода, которые могут не быть потокобезопасными.
-
Handler.acquire() -
Получает блокировку потока, созданную с помощью
createLock().
-
Handler.release() -
Освобождает блокировку потока, полученную с помощью
acquire().
-
Handler.setLevel(lvl) -
Устанавливает порог для этого обработчика на lvl. Сообщения журналов, которые менее серьезны, чем lvl, будут игнорироваться. При создании обработчика уровень устанавливается на
NOTSET(что приводит к обработке всех сообщений).См. Уровни регистрации для списка уровней.
Изменено в версии 3.2: Параметр lvl теперь принимает строковое представление уровня, например «INFO», как альтернативу целочисленным константам, таким как
INFO.
-
Handler.setFormatter(form) -
Устанавливает
Formatterдля этого обработчика на form.
-
Handler.addFilter(filt) -
Добавляет указанный фильтр filt в этот обработчик.
-
Handler.removeFilter(filt) -
Удаляет указанный фильтр filt из этого обработчика.
-
Handler.filter(record) -
Применяет фильтры обработчика к записи и возвращает значение true, если запись должна быть обработана. Фильтры проверяются по очереди, пока один из них не вернёт значение false. Если ни один из них не возвращает значение false, запись будет отображена. Если один из них возвращает false, обработчик не отобразит запись.
-
Handler.flush() -
Обеспечивает, что все выходные данные регистрации были сброшены. Эта версия ничего не делает и предназначена для реализации подклассами.
-
Handler.close() -
Очистка ресурсов, используемых обработчиком. Эта версия не производит вывод, но удаляет обработчик из внутреннего списка обработчиков, который закрывается при вызове
shutdown(). Подклассы должны гарантировать, что этот метод вызывается из переопределённых методовclose().
-
Handler.handle(record) -
Условно отображает указанную запись регистрации в зависимости от фильтров, которые могут быть добавлены в обработчик. Оборачивает фактическое отображение записи с получением/освобождением блокировки потока ввода-вывода.
-
Handler.handleError(record) -
Этот метод должен вызываться от обработчиков при возникновении исключения во время вызова
emit(). Если модульный атрибутraiseExceptionsравенFalse, исключения игнорируются без сообщений. Это то, что в основном требуется для системы регистрации - большинство пользователей не будут заботиться об ошибках в системе регистрации, их больше интересуют ошибки приложения. Однако вы можете заменить это пользовательским обработчиком, если хотите. Указанная запись — та, которая обрабатывалась при возникновении исключения. (Значение по умолчаниюraiseExceptionsравноTrue, так как это более полезно во время разработки).
-
Handler.format(record) -
Выполнить форматирование записи — если установлен форматировщик, использовать его. В противном случае использовать форматировщик по умолчанию для модуля.
-
Handler.emit(record) -
Выполнить необходимые действия для фактического протоколирования указанной записи регистрации. Эта версия предназначена для реализации подклассами и поэтому вызывает
NotImplementedError.
Для списка обработчиков, включённых по умолчанию, см. logging.handlers.
4. Объекты форматировщиков
Formatter объекты имеют следующие атрибуты и методы. Они отвечают за преобразование LogRecord в (обычно) строку, которую можно интерпретировать человеком или внешней системой. Базовый Formatter позволяет указать строку форматирования. Если она не указана, используется значение по умолчанию '%(message)s' , которое просто включает сообщение в вызов регистрации. Чтобы включить дополнительные элементы информации в отформатированный вывод (например, метку времени), продолжайте читать.
Форматировщик можно инициализировать строкой форматирования, которая использует знания атрибутов LogRecord — например, упомянутое выше значение по умолчанию использует тот факт, что сообщение пользователя и аргументы предварительно отформатированы в атрибут message LogRecord. Эта строка форматирования содержит стандартные ключи сопоставления в стиле Python %. См. раздел Форматирование строк в стиле printf для получения дополнительной информации о форматировании строк.
Полезные ключи сопоставления в LogRecord приведены в разделе о Атрибутах записи журнала.
-
class logging.Formatter(fmt=None, datefmt=None, style='%') -
Возвращает новый экземпляр класса
Formatter. Экземпляр инициализируется строкой формата для всего сообщения, а также строкой формата для части даты/времени сообщения. Если fmt не указан, используется'%(message)s'. Если datefmt не указан, используется формат даты ISO8601.Параметр style может быть одним из ‘%’, ‘{‘ или ‘$’ и определяет, как строка формата будет объединена со своими данными: используя %-форматирование,
str.format()илиstring.Template. Подробнее о использовании {- и $-форматирования для сообщений логов см. Использование определённых стилей форматирования в приложении.Изменено в версии 3.2: Добавлен параметр style.
-
format(record) -
Словарь атрибутов записи используется в качестве операнда для форматирования строки. Возвращает результирующую строку. Перед форматированием словаря выполняются несколько подготовительных шагов. Атрибут message записи вычисляется с использованием msg % args. Если строка формата содержит
'(asctime)', вызываетсяformatTime()для форматирования времени события. Если имеется информация об исключении, она форматируется с помощьюformatException()и добавляется к сообщению. Обратите внимание, что отформатированная информация об исключении кэшируется в атрибуте exc_text. Это полезно, потому что информация об исключении может быть сериализована и отправлена через сеть, но следует быть осторожным, если существует более одного класса-подклассаFormatter, который настраивает форматирование информации об исключении. В этом случае вам нужно будет очистить кэшированное значение после того, как форматировщик выполнил форматирование, чтобы следующий форматировщик, обрабатывающий событие, не использовал кэшированное значение, а пересчитал его заново.Если доступна информация о стеке, она добавляется после информации об исключении с использованием
formatStack()для преобразования, если необходимо.
-
formatTime(record, datefmt=None) -
Этот метод должен вызываться из
format()форматировщиком, который хочет использовать отформатированное время. Этот метод может быть переопределен в форматировщиках для удовлетворения любых особых требований, но основное поведение таково: если datefmt (строка) указан, он используется сtime.strftime()для форматирования времени создания записи. В противном случае используется формат ISO8601. Возвращается результирующая строка.Эта функция использует настраиваемую функцию для преобразования времени создания в кортеж. По умолчанию используется
time.localtime(); чтобы изменить это для конкретного экземпляра форматировщика, установите атрибутconverterв функцию с той же сигнатурой, что иtime.localtime()илиtime.gmtime(). Чтобы изменить его для всех форматировщиков, например, если вы хотите, чтобы все времена регистрации отображались в формате GMT, установите атрибутconverterв классеFormatter.Изменено в версии 3.3: Ранее, по умолчанию, формат ISO 8601 был жёстко закодирован, как в этом примере:
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(), но с последней новой строкой удалена) как строку. Эта реализация по умолчанию просто возвращает входное значение.
-
5. Объекты-фильтры
Filters могут использоваться Handlers и Loggers для более сложной фильтрации, чем обеспечивается уровнями. Базовый класс фильтра позволяет только событиям, которые находятся ниже определённой точки в иерархии логгеров. Например, фильтр, инициализированный ‘A.B’, позволит событиям, регистрируемым логгерами ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’ и т. д., но не ‘A.BB’, ‘B.A.B’ и т. д. Если инициализирован пустой строкой, все события пропускаются.
-
class logging.Filter(name='') -
Возвращает экземпляр класса
Filter. Если name указан, он задаёт имя логгера, который вместе со своими потомками будет иметь свои события, разрешённые через фильтр. Если name — пустая строка, разрешаются все события.-
filter(record) -
Должен ли указанный лог быть зарегистрирован? Возвращает ноль для нет, ненулевое значение для да. При необходимости запись может быть изменена на месте этим методом.
-
Обратите внимание, что фильтры, присоединённые к обработчикам, консультируются перед тем, как событие отправляется обработчиком, тогда как фильтры, присоединённые к логгерам, консультируются всякий раз, когда событие регистрируется (с помощью debug(), info() и т. д.), перед отправкой события обработчикам. Это означает, что события, сгенерированные дочерними логгерами, не будут отфильтрованы настройкой фильтра логгера, если фильтр не применён также к этим дочерним логгерам.
На самом деле вам не нужно подключать Filter: вы можете передать любой экземпляр, который имеет метод filter с такими же семантикой.
Изменено в версии 3.2: Вам не нужно создавать специализированные классы Filter, или использовать другие классы с методом filter: вы можете использовать функцию (или другой вызываемый объект) как фильтр. Логика фильтрации проверит, имеет ли объект фильтра атрибут filter: если он есть, предполагается, что это Filter, и вызывается его метод filter(). В противном случае предполагается, что это вызываемый объект, и он вызывается с записью в качестве единственного параметра. Возвращаемое значение должно соответствовать возвращаемому значению filter().
Хотя фильтры используются в основном для фильтрации записей на основе более сложных критериев, чем уровни, они видят каждую запись, которая обрабатывается обработчиком или логгером, к которому они присоединены: это может быть полезно, если вы хотите делать такие вещи, как подсчёт количества записей, обработанных определённым логгером или обработчиком, или добавлять, изменять или удалять атрибуты в обрабатываемой записи лога. Очевидно, что изменение записи лога требует осторожности, но это позволяет вставлять контекстную информацию в логи (см. Использование фильтров для передачи контекстной информации).
6. Объекты записей логов
LogRecord экземпляры создаются автоматически логгером Logger каждый раз, когда что-то регистрируется, и могут быть созданы вручную с помощью makeLogRecord() (например, из сериализованного события, полученного по сети).
-
class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None) -
Содержит всю информацию, относящуюся к событию, которое регистрируется.
Основная информация передается в
msgиargs, которые объединяются с помощьюmsg % argsдля создания поляmessageзаписи.Параметры: - name – Имя логгера, используемого для регистрации события, представленного этим объектом LogRecord. Обратите внимание, что это имя всегда будет иметь это значение, даже если оно может быть выведено обработчиком, присоединенным к другому (предковому) логгере.
-
level – Численный уровень события регистрации (один из DEBUG, INFO и т. д.). Обратите внимание, что это преобразуется в две атрибута LogRecord:
levelnoдля числового значения иlevelnameдля соответствующего имени уровня. - pathname – Полный путь к исходному файлу, где был сделан вызов регистрации.
- lineno – Номер строки в исходном файле, где был сделан вызов регистрации.
- msg – Сообщение описания события, возможно, строка формата с заполнительми для переменных данных.
- args – Переменные данные для объединения со значением msg для получения описания события.
-
exc_info – Кортеж исключения с текущей информацией об исключении или
None, если информация об исключении недоступна. - func – Имя функции или метода, из которого был вызван вызов регистрации.
- sinfo – Строка текста, представляющая информацию о стеке с начала стека в текущем потоке до вызова регистрации.
-
getMessage() -
Возвращает сообщение для этого объекта
LogRecordпосле объединения любых переданных пользователем аргументов с сообщением. Если переданное пользователем сообщение в вызове регистрации не является строкой,str()вызывается для преобразования его в строку. Это позволяет использовать пользовательские классы в качестве сообщений, метод__str__которых может возвращать фактическую строку формата, которая будет использована.
Изменено в версии 3.2: Создание
LogRecordбыло сделано более настраиваемым путем предоставления фабрики, которая используется для создания записи. Фабрику можно установить с помощьюgetLogRecordFactory()иsetLogRecordFactory()(см. эту информацию для подписи фабрики).Эта функциональность может быть использована для вставки собственных значений в LogRecord во время создания. Вы можете использовать следующий шаблон:
old_factory = logging.getLogRecordFactory() def record_factory(*args, **kwargs): record = old_factory(*args, **kwargs) record.custom_attribute = 0xdecafbad return record logging.setLogRecordFactory(record_factory)С этим шаблоном можно было бы объединить несколько фабрик, и, поскольку они не перезаписывают атрибуты друг друга или непреднамеренно не перезаписывают стандартные атрибуты, перечисленные выше, не должно быть никаких сюрпризов.
7. Атрибуты 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 | Часть имени файла в pathname. |
| funcName | %(funcName)s | Имя функции, содержащей вызов регистрации. |
| levelname | %(levelname)s | Текстовый уровень регистрации для сообщения ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'). |
| levelno | %(levelno)s | Числовой уровень регистрации для сообщения (DEBUG, INFO, WARNING, ERROR, CRITICAL). |
| lineno | %(lineno)d | Номер строки исходного кода, где был выдан вызов регистрации (если доступен). |
| module | %(module)s | Модуль (именная часть filename). |
| msecs | %(msecs)d | Миллисекундная часть времени создания LogRecord. |
| message | %(message)s | Зарегистрированное сообщение, вычисленное как msg %
args. Оно устанавливается при вызове Formatter.format(). |
| msg | Вам, скорее всего, не нужно будет это форматировать самостоятельно. | Строка формата, переданная в исходном вызове регистрации. Объединённая с args для получения message, или произвольный объект (см. Использование произвольных объектов в качестве сообщений). |
| name | %(name)s | Имя логгера, используемого для регистрации вызова. |
| pathname | %(pathname)s | Полный путь к исходному файлу, где был выдан вызов регистрации (если доступен). |
| process | %(process)d | Идентификатор процесса (если доступен). |
| processName | %(processName)s | Имя процесса (если доступно). |
| relativeCreated | %(relativeCreated)d | Время в миллисекундах, прошедшее с момента загрузки модуля регистрации до создания LogRecord. |
| stack_info | Вам, скорее всего, не нужно будет это форматировать самостоятельно. | Информация о кадре стека (если доступна) от нижней части стека в текущем потоке до и включая кадр стека вызова регистрации, который привел к созданию этой записи. |
| thread | %(thread)d | Идентификатор потока (если доступен). |
| threadName | %(threadName)s | Имя потока (если доступно). |
Изменено в версии 3.1: Добавлен атрибут processName.
8. Объекты LoggerAdapter
LoggerAdapter экземпляры используются для удобного передачи контекстной информации в вызовы регистрации. Пример использования см. в разделе Добавление контекстной информации в ваш лог-вывод.
-
class logging.LoggerAdapter(logger, extra) -
Возвращает экземпляр
LoggerAdapter, инициализированный с базовым объектомLoggerи объектом, похожим на словарь.-
process(msg, kwargs) -
Изменяет сообщение и/или ключевые аргументы, передаваемые в вызов регистрации, для вставки контекстной информации. Это реализация берет объект, переданный как extra конструктору, и добавляет его в kwargs с ключом ‘extra’. Возвращаемое значение — кортеж (msg, kwargs), содержащий (возможно измененные) версии аргументов, переданных в.
-
Помимо вышеперечисленного, LoggerAdapter поддерживает следующие методы Logger: debug(), info(), warning(), error(), exception(), critical(), log(), isEnabledFor(), getEffectiveLevel(), setLevel() и hasHandlers(). Эти методы имеют такие же сигнатуры, как и их аналоги в Logger, поэтому вы можете использовать оба типа экземпляров взаимозаменяемо.
Изменено в версии 3.2: Методы isEnabledFor(), getEffectiveLevel(), setLevel() и hasHandlers() были добавлены в LoggerAdapter. Эти методы делегируют вызовы базовому логгеру.
9. Безопасность потоков
Модуль logging предназначен для обеспечения потокобезопасности без необходимости выполнения каких-либо специальных действий со стороны клиентов. Это достигается с помощью потоковых блокировок; имеется одна блокировка для сериализации доступа к общим данным модуля, и каждый обработчик также создаёт блокировку для сериализации доступа к его базовому вводу-выводу.
Если вы реализуете асинхронные обработчики сигналов с использованием модуля signal, вы, возможно, не сможете использовать logging внутри таких обработчиков. Это связано с тем, что реализации блокировок в модуле threading не всегда являются рекурсивными, и поэтому не могут быть вызваны из таких обработчиков сигналов.
10. Функции уровня модуля
Помимо описанных выше классов, существует ряд функций уровня модуля.
-
logging.getLogger(name=None) -
Возвращает логгер с указанным именем или, если имя равно
None, возвращает корневой логгер иерархии. Если задано, имя обычно представляет собой иерархическое имя, разделённое точками, например, ‘a’, ‘a.b’ или ‘a.b.c.d’. Выбор этих имён полностью зависит от разработчика, использующего logging.Все вызовы этой функции с данным именем возвращают один и тот же экземпляр логгера. Это означает, что экземпляры логгеров никогда не нужно передавать между разными частями приложения.
-
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. Если он равен true, к сообщению логирования добавляется информация о стеке вызовов, включая фактический вызов логирования. Обратите внимание, что это не та же информация о стеке, что и при указании 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для получения дополнительной информации о том, какие ключи используются системой логирования.)Если вы решите использовать эти атрибуты в зарегистрированных сообщениях, вам нужно проявить осторожность. Например, в приведённом выше примере форматтер
Formatterбыл настроен с помощью строки формата, которая ожидает наличие «clientip» и «user» в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет записано, поскольку произойдёт исключение форматирования строк. Поэтому в этом случае вам всегда нужно передавать словарь extra с этими ключами.Хотя это может быть неудобно, эта функция предназначена для использования в специализированных ситуациях, таких как многопотоковые серверы, где один и тот же код выполняется во многих контекстах, и интересные условия, которые возникают, зависят от этого контекста (например, удалённый IP-адрес клиента и имя аутентифицированного пользователя в приведённом выше примере). В таких ситуациях, скорее всего, будут использоваться специализированные форматеры
Formatterсо специфическимиHandler.Добавлено в версии 3.2: Параметр stack_info был добавлен.
-
logging.info(msg, *args, **kwargs) -
Записывает сообщение с уровнем
INFOв корневой логгер. Аргументы интерпретируются так же, как вdebug().
-
logging.warning(msg, *args, **kwargs) -
Записывает сообщение с уровнем
WARNINGв корневой логгер. Аргументы интерпретируются так же, как вdebug().Примечание
Существует устаревшая функция
warn, функционально идентичнаяwarning. Посколькуwarnустарела, не используйте её — используйтеwarningвместо неё.
-
logging.error(msg, *args, **kwargs) -
Записывает сообщение с уровнем
ERRORв корневой логгер. Аргументы интерпретируются так же, как вdebug().
-
logging.critical(msg, *args, **kwargs) -
Записывает сообщение с уровнем
CRITICALв корневой логгер. Аргументы интерпретируются так же, как вdebug().
-
logging.exception(msg, *args, **kwargs) -
Записывает сообщение с уровнем
ERRORв корневой логгер. Аргументы интерпретируются так же, как и вdebug(). В сообщение об ошибке добавляется информация об исключении. Эту функцию следует вызывать только из обработчика исключений.
-
logging.log(level, msg, *args, **kwargs) -
Записывает сообщение с уровнем level в корневой логгер. Остальные аргументы интерпретируются так же, как и в
debug().Примечание
Функции-удобства на уровне модуля, которые делегируют запрос к корневому логгеру, вызывают
basicConfig()для обеспечения наличия по крайней мере одного обработчика. Из-за этого их следует не использовать в потоках в версиях Python, более ранних чем 2.7.1 и 3.2, если по крайней мере один обработчик не был добавлен в корневой логгер до запуска потоков. В более ранних версиях Python из-за недостатка потоковой безопасности вbasicConfig()это (в редких случаях) может привести к добавлению обработчиков в корневой логгер несколько раз, что, в свою очередь, может привести к нескольким сообщениям об одном и том же событии.
-
logging.disable(lvl) -
Предоставляет переопределяющий уровень lvl для всех логгеров, который имеет приоритет над собственным уровнем логгера. Когда возникает необходимость временно уменьшить выходные данные регистрации по всему приложению, эта функция может быть полезна. Ее действие заключается в отключении всех вызовов регистрации с уровнем серьезности lvl и ниже, так что если вы вызовете ее со значением INFO, все события INFO и DEBUG будут отброшены, а события с уровнем серьезности WARNING и выше будут обработаны в соответствии с эффективным уровнем логгера. Если вызовут
logging.disable(logging.NOTSET), это фактически удалит этот переопределяющий уровень, поэтому выходные данные регистрации снова будут зависеть от эффективных уровней отдельных логгеров.
-
logging.addLevelName(lvl, levelName) -
Связывает уровень lvl с текстом levelName во внутренней таблице, которая используется для сопоставления числовых уровней с текстовым представлением, например, при форматировании сообщения
Formatter. Эту функцию также можно использовать для определения собственных уровней. Единственные ограничения заключаются в том, что все используемые уровни должны быть зарегистрированы с помощью этой функции, уровни должны быть положительными целыми числами и они должны возрастать в порядке возрастания серьезности.Примечание
Если вы хотите определить свои собственные уровни, см. раздел Пользовательские уровни.
-
logging.getLevelName(lvl) -
Возвращает текстовое представление уровня регистрации lvl. Если уровень является одним из предопределенных уровней
CRITICAL,ERROR,WARNING,INFOилиDEBUG, то вы получите соответствующую строку. Если вы связали уровни с именами с помощьюaddLevelName(), то возвращается имя, которое вы связали с lvl. Если передано числовое значение, соответствующее одному из определенных уровней, возвращается соответствующее строковое представление. В противном случае возвращается строка ‘Уровень %s’ % lvl.Примечание
Уровни внутренне являются целыми числами (так как они должны сравниваться в логике регистрации). Эта функция используется для преобразования между целым уровнем и именем уровня, отображаемым в отформатированном выводе журнала с помощью спецификатора формата
%(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(), если для корневого логгера не определены обработчики.Эта функция ничего не делает, если корневой логгер уже имеет настроенные обработчики.
Примечание
Эта функция должна вызываться из основного потока перед запуском других потоков. В версиях Python до 2.7.1 и 3.2, если эта функция вызывается из нескольких потоков, в редких случаях возможно, что обработчик будет добавлен в корневой логгер более одного раза, что приведет к неожиданным результатам, таким как дублирование сообщений в журнале.
Поддерживаются следующие ключевые аргументы.
Формат Описание filenameУказывает на создание FileHandler с указанным именем файла вместо StreamHandler. filemodeЗадает режим открытия файла, если указано имя файла (если filemode не указан, он по умолчанию равен ‘a’). formatИспользует указанную строку формата для обработчика. datefmtИспользует указанный формат даты/времени. styleЕсли formatуказано, используйте этот стиль для строки формата. Один из ‘%’, ‘{‘ или ‘$’ для %-форматирования,str.format()илиstring.Templateсоответственно, по умолчанию ‘%’, если не указано.levelУстанавливает уровень корневого логгера на указанный уровень. streamИспользуйте указанный поток для инициализации StreamHandler. Обратите внимание, что этот аргумент несовместим с ‘filename’ - если оба присутствуют, возникает ValueError.handlersЕсли указано, это должен быть итерируемый объект уже созданных обработчиков для добавления в корневой логгер. Любые обработчики, у которых еще нет установленного форматировщика, будут назначены созданный в этой функции форматировщик по умолчанию. Обратите внимание, что этот аргумент несовместим с ‘filename’ или ‘stream’ - если оба присутствуют, возникает ValueError.Изменено в версии 3.2: Добавлен аргумент
style.Изменено в версии 3.3: Добавлен аргумент
handlers. Были добавлены дополнительные проверки для обнаружения ситуаций, где указаны несовместимые аргументы (например,handlersвместе сstreamилиfilename, илиstreamвместе сfilename).
-
logging.shutdown() -
Уведомляет систему регистрации о выполнении упорядоченного завершения работы, очищая и закрывая все обработчики. Это должно вызываться при завершении работы приложения, и после этого вызова система регистрации больше не должна использоваться.
-
logging.setLoggerClass(klass) -
Уведомляет систему регистрации использовать класс klass при создании логгера. Класс должен определять
__init__()таким образом, чтобы требовался только аргумент имени, и__init__()должен вызыватьLogger.__init__(). Эта функция обычно вызывается приложениями, которым требуется пользовательское поведение логгера, до создания любых логгеров.
-
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: Дополнительные ключевые аргументы.
11. Атрибуты уровня модуля
-
logging.lastResort -
«Обработчик последней инстанции» доступен через этот атрибут. Это
StreamHandler, записывающий вsys.stderrс уровнемWARNING, и используется для обработки событий ведения журнала в отсутствие какой-либо конфигурации ведения журнала. Результатом является просто вывод сообщения вsys.stderr. Это заменяет более раннее сообщение об ошибке, говорящее, что «для логгера XYZ не удалось найти обработчиков». Если по какой-то причине вам нужен более ранний метод работы,lastResortможно установить вNone.Введено в версии 3.2.
12. Интеграция с модулем 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–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/logging.html