Spec-Zone.ru › Python 3.7

logging — Модуль ведения логов для Python

Исходный код: Lib/logging/__init__.py

Важно

Эта страница содержит справочную информацию по API. Для получения информации по учебникам и обсуждения более сложных тем, см.

  • Базовый учебник
  • Расширенный учебник
  • Руководство по ведению логов

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

Ключевым преимуществом наличия API ведения логов в стандартном модуле является то, что все модули Python могут участвовать в ведении логов, поэтому ваш лог приложения может включать ваши собственные сообщения, интегрированные с сообщениями сторонних модулей.

Модуль предоставляет множество функций и гибкости. Если вы не знакомы с ведением логов, лучший способ разобраться в нём — изучить учебники (см. ссылки справа).

Основные классы, определённые в модуле, вместе со своими функциями, перечислены ниже.

  • Логгеры предоставляют интерфейс, который непосредственно используется кодом приложения.
  • Обработчики отправляют записи логов (созданные логгерами) в соответствующее место назначения.
  • Фильтры обеспечивают более тонкую настройку для определения, какие записи логов выводить.
  • Форматировщики задают формат записей логов в окончательном выводе.

Объекты логгера

Логгеры имеют следующие атрибуты и методы. Обратите внимание, что логгеры НИКОГДА не следует создавать напрямую, а всегда через функцию модуля 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
propagate

Если это атрибут имеет значение true, события, записанные в этот логгер, будут переданы обработчикам логгеров более высокого уровня (предкам), помимо любых обработчиков, присоединённых к этому логгере. Сообщения передаются непосредственно обработчикам логгеров предков — ни уровень, ни фильтры предков не учитываются.

Если это значение равно 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 с помощью оператора форматирования строк. (Обратите внимание, что это означает, что вы можете использовать ключевые слова в строке формата вместе с единственным аргументом словаря.)

В kwargs проверяются три ключевых аргумента: exc_info, stack_info и extra.

Если 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'}
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 теперь может принимать экземпляры исключений.

info(msg, *args, **kwargs)

Записывает сообщение с уровнем INFO в этот логгер. Аргументы интерпретируются так же, как для debug().

warning(msg, *args, **kwargs)

Записывает сообщение с уровнем WARNING в этот логгер. Аргументы интерпретируются так же, как для debug().

Примечание

Существует устаревший метод warn функционально идентичный warning. Поскольку warn устарел, не используйте его — используйте warning вместо него.

error(msg, *args, **kwargs)

Записывает сообщение с уровнем ERROR в этот логгер. Аргументы интерпретируются так же, как для debug().

critical(msg, *args, **kwargs)

Записывает сообщение с уровнем CRITICAL в этот логгер. Аргументы интерпретируются так же, как для debug().

log(level, msg, *args, **kwargs)

Записывает сообщение с целым уровнем level в этот логгер. Остальные аргументы интерпретируются так же, как для debug().

exception(msg, *args, **kwargs)

Записывает сообщение с уровнем ERROR в этот логгер. Аргументы интерпретируются так же, как для debug(). Информация об исключении добавляется в сообщение логирования. Этот метод должен вызываться только из обработчика исключений.

addFilter(filter)

Добавляет указанный фильтр filter в этот логгер.

removeFilter(filter)

Удаляет указанный фильтр filter из этого регистратора.

filter(record)

Применяет фильтры этого регистратора к записи и возвращает True, если запись должна быть обработана. Фильтры проверяются по очереди, пока один из них не вернёт значение false. Если ни один из фильтров не возвращает false, запись будет обработана (передана обработчикам). Если один из фильтров возвращает false, дальнейшая обработка записи не происходит.

addHandler(hdlr)

Добавляет указанный обработчик hdlr к этому регистратору.

removeHandler(hdlr)

Удаляет указанный обработчик hdlr из этого регистратора.

findCaller(stack_info=False)

Находит имя файла и номер строки вызывающей функции. Возвращает имя файла, номер строки, имя функции и информацию о стеке в виде кортежа из 4 элементов. Информация о стеке возвращается как None если stack_info не True.

handle(record)

Обрабатывает запись, передавая её всем обработчикам, связанным с этим регистратором и его предками (до тех пор, пока не будет найдено значение propagate равное false). Этот метод используется для десериализованных записей, полученных через сокет, а также для записей, созданных локально. Фильтрация на уровне регистратора применяется с помощью filter().

makeRecord(name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)

Это фабричный метод, который может быть переопределён в подклассах для создания специализированных экземпляров LogRecord.

hasHandlers()

Проверяет, есть ли у этого регистратора какие-либо обработчики. Это делается путём поиска обработчиков в этом регистраторе и его родителях в иерархии регистраторов. Возвращает True если обработчик найден, иначе False. Поиск по иерархии прекращается, когда обнаруживается регистратор с атрибутом ‘propagate’ установленным в false — это последний регистратор, в котором проверяется наличие обработчиков.

Новое в версии 3.2.

Изменено в версии 3.7: Теперь регистраторы могут быть сериализованы и десериализованы.

Уровни ведения журналов

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

Уровень

Числовое значение

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, если запись должна быть обработана. Фильтры проверяются по очереди, пока один из них не вернёт значение false. Если ни один из фильтров не возвращает false, запись будет отправлена. Если один из фильтров возвращает false, обработчик не отправит запись.

flush()

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

close()

Очищает ресурсы, используемые обработчиком. Эта версия не выводит ничего, но удаляет обработчик из внутреннего списка обработчиков, который закрывается при вызове shutdown(). Подклассы должны убедиться, что это вызывается из переопределённых методов close().

handle(record)

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

handleError(record)

Этот метод должен вызываться из обработчиков, когда во время вызова emit() возникает исключение. Если модульный атрибут raiseExceptions равен False, исключения игнорируются без вывода сообщения об ошибке. Это то, что обычно требуется для системы ведения журналов — большинство пользователей не будут обращать внимание на ошибки в системе ведения журналов, они больше заинтересованы в ошибках приложения. Вы можете заменить это пользовательским обработчиком, если хотите. Указанная запись — та, которая обрабатывалась, когда возникло исключение. (Значение по умолчанию raiseExceptions равно True, так как это более полезно во время разработки).

format(record)

Выполнить форматирование записи — если установлен форматировщик, используйте его. В противном случае используйте форматировщик по умолчанию для модуля.

emit(record)

Выполните необходимые действия для записи указанной записи журнала. Эта версия предназначена для реализации подклассами и поэтому вызывает NotImplementedError.

Список стандартных обработчиков см. в logging.handlers.

Объекты форматировщиков

Formatter объекты имеют следующие атрибуты и методы. Они отвечают за преобразование LogRecord в (обычно) строку, которая может быть интерпретирована человеком или внешней системой. Базовый Formatter позволяет указать строку форматирования. Если она не указана, используется значение по умолчанию '%(message)s', которое просто включает сообщение в вызов ведения журнала. Чтобы добавить в отформатированный вывод дополнительную информацию (например, отметку времени), читайте дальше.

Форматировщик может быть инициализирован строкой форматирования, которая использует знания об атрибутах LogRecord — например, о значениях по умолчанию, упомянутых выше, используя тот факт, что сообщение пользователя и аргументы предварительно отформатированы в атрибут message объекта LogRecord. Эта строка форматирования содержит стандартные ключи сопоставления в стиле Python %. Дополнительную информацию о форматировании строк см. в разделе Форматирование строк в стиле printf.

Полезные ключи сопоставления в объекте LogRecord приведены в разделе о атрибутах LogRecord.

class logging.Formatter(fmt=None, datefmt=None, style='%')

Возвращает новый экземпляр класса Formatter. Экземпляр инициализируется строкой форматирования для всего сообщения, а также строкой форматирования для части даты/времени сообщения. Если fmt не указан, используется '%(message)s'. Если datefmt не указан, используется формат, описанный в документации formatTime().

Параметр 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() для форматирования времени создания записи. В противном случае используется формат ‘%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(), но с удалённой последней новой строкой) в виде строки. Эта реализация по умолчанию просто возвращает входное значение.

Объекты фильтров

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().

Хотя фильтры используются в первую очередь для фильтрации записей на основе более сложных критериев, чем уровни, они видят каждую запись, которая обрабатывается обработчиком или логгером, к которому они прикреплены: это может быть полезно, если вы хотите выполнить такие действия, как подсчёт количества записей, обработанных определённым логгером или обработчиком, или добавление, изменение или удаление атрибутов в обрабатываемой записи 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 – Полный путь к исходному файлу, в котором был сделан вызов логирования.
  • 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)

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

Атрибуты 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

Номер строки исходного кода, где был выпущен вызов логирования (если доступен).

message

%(message)s

Записанное сообщение, вычисленное как msg % args. Устанавливается при вызове Formatter.format().

module

%(module)s

Модуль (имя части filename).

msecs

%(msecs)d

Миллисекундная часть времени, когда был создан LogRecord.

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.

Объекты 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. Эти методы делегируют базовому журналу.

Безопасность потоков

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

Если вы реализуете обработчики асинхронных сигналов, используя модуль signal, вы можете не иметь возможности использовать регистрацию событий внутри таких обработчиков. Это связано с тем, что реализации блокировок в модуле threading не всегда являются рекурсивными, и поэтому не могут вызываться из таких обработчиков сигналов.

Функции уровня модуля

В дополнение к описанным выше классам существует ряд функций уровня модуля.

logging.getLogger(name=None)

Возвращает журнал с указанным именем или, если имя равно None, возвращает журнал, который является корневым журналом иерархии. Если указано, имя обычно является иерархическим именем, разделённым точками, например, ‘a’, ‘a.b’ или ‘a.b.c.d’. Выбор этих имён полностью зависит от разработчика, использующего регистрацию.

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

logging.getLoggerClass()

Возвращает стандартный класс Logger или последний класс, переданный в setLoggerClass(). Эта функция может вызываться внутри нового определения класса, чтобы гарантировать, что установка настраиваемого класса Logger не отменит уже применённые настройки другим кодом. Например:

class MyLogger(logging.getLoggerClass()):
    # ... override behaviour here
logging.getLogRecordFactory()

Возвращает вызываемый объект, используемый для создания LogRecord.

Добавлена в версии 3.2: Эта функция была предоставлена вместе с setLogRecordFactory(), чтобы дать разработчикам больший контроль над тем, как создаётся LogRecord, представляющий событие регистрации.

См. setLogRecordFactory() для получения дополнительной информации о том, как вызывается фабрика.

logging.debug(msg, *args, **kwargs)

Регистрирует сообщение с уровнем DEBUG в корневом журнале. msg — строка формата сообщения, а args — аргументы, которые объединяются в msg с помощью оператора форматирования строк. (Обратите внимание, что это означает, что вы можете использовать ключевые слова в строке формата вместе с одним аргументом-словарем.)

В kwargs проверяются три ключевых аргумента: exc_info, который, если он не оценивается как ложь, вызывает добавление информации об исключении к сообщению регистрации. Если предоставляется кортеж исключения (в формате, возвращаемом sys.exc_info()) или экземпляр исключения, он используется; в противном случае вызывается sys.exc_info(), чтобы получить информацию об исключении.

Второй необязательный ключевой аргумент — stack_info, который по умолчанию равен False. Если он равен истине, в сообщение регистрации добавляется информация о стеке, включая фактический вызов регистрации. Обратите внимание, что это не та же информация о стеке, что и при указании exc_info: Первая — кадры стека снизу до вызова регистрации в текущем потоке, а вторая — информация о кадрах стека, которые были развёрнуты после возникновения исключения при поиске обработчиков исключений.

Вы можете указать stack_info независимо от exc_info, например, чтобы просто показать, как вы попали в определённую точку вашего кода, даже когда не было никаких исключений. Кадры стека выводятся после строки заголовка, которая гласит:

Stack (most recent call last):

Это имитирует Traceback (most recent call last): , используемый при отображении кадров исключений.

Третий необязательный ключевой аргумент — extra, который можно использовать для передачи словаря, который используется для заполнения __dict__ созданного для события регистрации LogRecord пользовательскими атрибутами. Эти пользовательские атрибуты могут использоваться по своему усмотрению. Например, они могут быть включены в зарегистрированные сообщения. Например:

FORMAT = '%(asctime)-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(level=CRITICAL)

Предоставляет переопределяющий уровень level для всех логгеров, который имеет приоритет над собственным уровнем логгера. Когда возникает необходимость временно ограничить выходные данные логгирования по всему приложению, эта функция может быть полезной. Её эффект заключается в отключении всех вызовов логгирования с уровнем level и ниже, так что если вы вызовете её со значением INFO, то все события INFO и DEBUG будут отброшены, а события WARNING и выше будут обработаны в соответствии с эффективным уровнем логгера. Если вызов logging.disable(logging.NOTSET), то это фактически удаляет этот переопределяющий уровень, так что выходные данные логгирования снова зависят от эффективных уровней отдельных логгеров.

Обратите внимание, что если вы определили какие-либо пользовательские уровни логгирования, которые выше CRITICAL (это не рекомендуется), вы не сможете полагаться на значение по умолчанию для параметра level, а придётся явно указать подходящее значение.

Изменено в версии 3.7: Параметр level был задан по умолчанию в уровень CRITICAL. См. выпуск #28524 для получения дополнительной информации об этом изменении.

logging.addLevelName(level, levelName)

Связывает уровень level с текстом levelName во внутренней таблице, которая используется для сопоставления числовых уровней с текстовым представлением, например, когда Formatter форматирует сообщение. Эта функция также может использоваться для определения собственных уровней. Единственными ограничениями являются то, что все используемые уровни должны быть зарегистрированы с помощью этой функции, уровни должны быть положительными целыми числами и они должны возрастать в порядке возрастания степени серьёзности.

Примечание

Если вы думаете о определении собственных уровней, пожалуйста, ознакомьтесь с разделом о Пользовательские уровни.

logging.getLevelName(level)

Возвращает текстовое представление уровня логгирования level. Если уровень является одним из предопределённых уровней CRITICAL, ERROR, WARNING, INFO или DEBUG, то вы получите соответствующую строку. Если вы ассоциировали уровни с именами с помощью addLevelName(), то возвращается имя, которое вы ассоциировали с 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(), если для корневого логгера не определены обработчики.

Эта функция ничего не делает, если для корневого логгера уже настроены обработчики.

Примечание

Данную функцию необходимо вызывать из основного потока перед запуском других потоков. В версиях 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.

Изменено в версии 3.2: Добавлен аргумент style.

Изменено в версии 3.3: Добавлен аргумент handlers. Добавлены дополнительные проверки для обнаружения ситуаций, когда указаны несовместимые аргументы (например, handlers вместе с stream или filename, или stream вместе с filename).

logging.shutdown()

Информирует систему логирования о выполнении упорядоченной остановки путём сброса и закрытия всех обработчиков. Это нужно вызывать при выходе приложения, и после этого вызова больше нельзя использовать систему логирования.

logging.setLoggerClass(klass)

Указывает системе логирования использовать класс klass при создании логгера. Класс должен определять __init__() таким образом, чтобы требовался только аргумент имени, и __init__() должен вызывать Logger.__init__(). Обычно эта функция вызывается перед созданием любых логгеров приложениями, которые нуждаются в пользовательском поведении логгера. После этого вызова, как и в любое другое время, не создавайте логгеры напрямую с помощью подкласса: продолжайте использовать API logging.getLogger() для получения логгеров.

logging.setLogRecordFactory(factory)

Устанавливает вызываемый объект, который используется для создания LogRecord.

Параметры

factory – Вызываемый объект-фабрика для создания записи лога.

Новое в версии 3.2: Эта функция, вместе с getLogRecordFactory(), предоставляется, чтобы предоставить разработчикам больший контроль над тем, как строится LogRecord, представляющий событие логирования.

Фабрика имеет следующий сигнатуру:

factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)

name

Имя логгера.

level

Уровень логирования (числовое значение).

fn

Полный путь к файлу, где был вызван лог.

lno

Номер строки в файле, где был вызван лог.

msg

Сообщение лога.

args

Аргументы для сообщения лога.

exc_info

Кортеж исключения или None.

func

Имя функции или метода, которые вызвали лог.

sinfo

Стек отладки, как предоставляется traceback.print_stack(), показывающий иерархию вызовов.

kwargs

Дополнительные ключевые аргументы.

Атрибуты уровня модуля

logging.lastResort

«Обработчик последней инстанции» доступен через этот атрибут. Это StreamHandler, пишущий в sys.stderr с уровнем WARNING, и используется для обработки событий логирования в отсутствие какой-либо конфигурации логирования. Результатом является просто вывод сообщения в sys.stderr. Это заменяет предыдущее сообщение об ошибке, говорившее о том, что «для логгера XYZ не было найдено обработчиков». Если вам по какой-то причине нужно прежнее поведение, lastResort можно установить в значение None.

Новое в версии 3.2.

Интеграция с модулем warnings

Функция captureWarnings() может использоваться для интеграции logging с модулем warnings.

logging.captureWarnings(capture)

Эта функция используется для включения и отключения захвата предупреждений системой логирования.

Если capture равно True, предупреждения, выданные модулем warnings, будут перенаправлены в систему логирования. В частности, предупреждение будет отформатировано с помощью warnings.formatwarning(), а полученная строка будет записана в логгер с именем 'py.warnings' с уровнем WARNING.

Если capture равно False, перенаправление предупреждений в систему логирования прекратится, и предупреждения будут перенаправлены в их исходные места назначения (то есть те, которые действовали до вызова captureWarnings(True)).

См. также

Module logging.config

API конфигурации модуля регистрации событий.

Module logging.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.7/library/logging.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API