logging — Логирование для Python


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

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

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

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

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

Logger объекты

У логгеров есть следующие атрибуты и методы. Обратите внимание, что для логгеров НЕЛЬЗЯ создавать экземпляры напрямую, вместо этого вызывается функция logging.getLogger(name) на уровне модуля. Несколько вызовов getLogger() с одним и тем же именем всегда будут возвращать ссылку на один и тот же Logger объект.

name потенциально является иерархическим значением, разделенным точками, например foo.bar.baz (хотя может быть просто foo, например). Логгеры, расположенные ниже в иерархическом списке, являются потомками логгеров выше в списке. Например, для логгера с именем foo, логгеры с именами foo.bar, foo.bar.baz и foo.bam являются потомками foo. Иерархия имён логгеров аналогична иерархии пакетов Python и идентична ей, если вы организовываете свои логгеры для каждого модуля с использованием рекомендуемой конструкции logging.getLogger(__name__). Это так, потому что в модуле __name__ — имя модуля в пространстве имён пакета Python.

class logging.Logger
propagate

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

Если принимает значение false, сообщения журнала не передаются обработчикам логирования предков.

Конструктор устанавливает для данного атрибута значение True.

Примечание

Если прикрепить обработчик к логгеру и к одному или нескольким его предков, он может генерировать одну и ту же запись несколько раз. В общем, не нужно прикреплять обработчик к более чем одному логгеру — если прикрепить его к соответствующему логгеру, который находится наверху в иерархии логгера, тогда он будет видеть все события, зарегистрированные всеми дочерними логгерами при условии, что для их параметра propagate установлено значение True. Общий сценарий состоит в том, чтобы прикрепить обработчики только к корневому логгеру и разрешить распространению заботится обо всех остальных.

setLevel(level)

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

При создании логгера устанавливается уровень NOTSET (что приводит к тому, что все сообщения обрабатываются, когда логгер является корневым логгером, или делегируются родительскому объекту, когда логгер не является корневым логгером). Обратите внимание, что корневой логгер создаётся с уровнем WARNING.

Термин «делегирование родителю» означает, что если у логгера уровень NOTSET, цепочка его логгеров предков просматривается до тех пор, пока не будет найден предок с уровнем, отличным от NOTSET, или не будет достигнут корень.

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

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

Список уровней см. в Уровни ведения журнала.

Изменено в версии 3.2: Параметр level теперь принимает строковое представление, такое как «INFO», в качестве альтернативы целочисленным константам, таким как INFO. Обратите внимание, однако, что уровни внутри хранятся как целые числа, а такие методы, как, например, getEffectiveLevel() и isEnabledFor() будут возвращать/ожидать передачи целых чисел.

isEnabledFor(level)

Указывает, будет ли обработано данным логгером сообщение с серьезностью level. Метод проверяет сначала уровень модуля, установленный logging.disable(level), а затем эффективный уровень логгера, определенный getEffectiveLevel().

getEffectiveLevel()

Указывает эффективный уровень для данного логгера. Если значение, отличное от NOTSET, было установлено с помощью setLevel(), оно возвращается. В противном случае иерархия перемещается к корню до тех пор, пока не будет найдено значение, отличное от NOTSET, и это значение не будет возвращено. Возвращаемое значение является целым числом, обычно одним из logging.DEBUG, logging.INFO и т. д.

getChild(suffix)

Возвращает логгер, которое является потомком данного логгера, как определено суффиксом. Таким образом, logging.getLogger('abc').getChild('def.ghi') вернёт тот же логгер, что и logging.getLogger('abc.def.ghi'). Удобный и полезный метод, когда родительский логгер именуется с использованием, например __name__, а не литеральной строкой.

Добавлено в версии 3.2.

debug(msg, *args, **kwargs)

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

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

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

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

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

Stack (most recent call last):

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

Третий необязательный ключевой аргумент — stacklevel, значение по умолчанию — 1. Если больше 1, соответствующее количество фреймов стека пропускается при вычислении номера строки и имени функции, заданных в LogRecord, созданном для события логирования. Его можно использовать в помощниках ведения журнала, чтобы записанные имя функции, имя файла и номер строки не были информацией для вспомогательной функции/метода, а скорее были её вызывающей стороной. Имя этого параметра отражает эквивалентное имя в модуле warnings.

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

FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logger = logging.getLogger('tcpserver')
logger.warning('Protocol problem: %s', 'connection reset', extra=d)

напечатал бы что-то вроде

2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset

Ключи в словаре, переданном в extra, не должны конфликтовать с ключами, используемыми системой логирования. (См. документацию Formatter для получения дополнительной информации о том, какие ключи используются системой логирования.)

Если вы решите использовать данные атрибуты в регистрируемых сообщениях, вам нужно проявить некоторую осторожность. В приведенном выше примере, например, Formatter был настроен со строкой формата, которая ожидает «clientip» и «user» в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет зарегистрировано, поскольку возникнет исключение форматирования строки. Таким образом, в этом случае вам всегда нужно передавать словарь extra с этими ключами.

Хотя это может раздражать, функция предназначена для использования в особых обстоятельствах, таких как многопоточные серверы, на которых один и тот же код выполняется во многих контекстах, и возникающие интересные условия зависят от контекста (например, IP-адрес удаленного клиента и аутентификация имя пользователя, в приведенном выше примере). В таких обстоятельствах вполне вероятно, что специализированные Formatterы будут использоваться с Handlerами.

Изменено в версии 3.2: Добавлен параметр stack_info.

Изменено в версии 3.5: Параметр exc_info теперь может принимать экземпляры исключений.

Изменено в версии 3.8: Добавлен параметр stacklevel.

info(msg, *args, **kwargs)

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

warning(msg, *args, **kwargs)

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

Примечание

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

error(msg, *args, **kwargs)

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

critical(msg, *args, **kwargs)

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

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

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

exception(msg, *args, **kwargs)

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

addFilter(filter)

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

removeFilter(filter)

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

filter(record)

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

addHandler(hdlr)

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

removeHandler(hdlr)

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

findCaller(stack_info=False, stacklevel=1)

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

Параметр stacklevel передаётся из кода, вызывающего debug() и другие API. Если больше 1, избыток используется для пропуска фреймов стека перед определением возвращаемых значений. Как правило, это будет полезно при вызове API логгера из кода помощника/оболочки, чтобы информация в журнале событий относилась не к коду помощника/оболочки, а к коду, который его вызывает.

handle(record)

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

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

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

hasHandlers()

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

Добавлено в версии 3.2.

Изменено в версии 3.7: Логгеры теперь можно пиклить (pickled) и анпиклить (unpickled).

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

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

Уровень Числовое значение
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

Объекты-обработчики

У обработчиков есть следующие атрибуты и методы. Обратите внимание, что Handler никогда не создаётся напрямую; данный класс выступает в качестве основы для более полезных подклассов. Однако метод __init__() в подклассах должен вызывать Handler.__init__().

class logging.Handler
__init__(level=NOTSET)

Инициализирует экземпляр Handler, устанавливая его уровень, устанавливая для списка фильтров пустой список и создавая блокировку (с использованием createLock()) для сериализации доступа к механизму ввода-вывода.

createLock()

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

acquire()

Получает блокировку потока, созданную с помощью createLock().

release()

Освобождает блокировку потока, полученной с помощью acquire().

setLevel(level)

Устанавливает порог для обработчика равным level. Сообщения журнала, которые менее серьезны, чем level, будут игнорироваться. Когда создается обработчик, устанавливается уровень NOTSET (что вызывает обработку всех сообщений).

Список уровней см. в Уровни ведения журнала.

Изменено в версии 3.2: Параметр level теперь принимает строковое представление уровня, такое как INFO, в качестве альтернативы целочисленным константам, таким как INFO.

setFormatter(fmt)

Устанавливает Formatter для обработчика на fmt.

addFilter(filter)

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

removeFilter(filter)

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

filter(record)

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

flush()

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

close()

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

handle(record)

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

handleError(record)

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

format(record)

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

emit(record)

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

Для получения списка стандартных обработчиков см. в logging.handlers.

Formatter объекты

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

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

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

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

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

Параметр style может быть одним из «%», «{» или «$» и определяет, как строка формата будет объединена с её данными: с использованием одного из %-форматирования, str.format() или string.Template. См. Использование определенных стилей форматирования во всём приложении для получения дополнительной информации об использовании {- и $ -форматировании для сообщений журнала.

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

Изменено в версии 3.8: Добавлен параметр validate. Неправильный или несоответствующий стиль и fmt вызовут ValueError. Например: logging.Formatter('%(asctime)s - %(message)s', style='{').

format(record)

Словарь атрибутов записи используется в качестве операнда для операции форматирования строки. Возвращает результирующую строку. Перед форматированием словаря проводится пара подготовительных шагов. Атрибут записи message вычисляется с использованием msg % args. Если строка форматирования содержит '(asctime)', вызывается formatTime() для форматирования времени события. Если есть информация об исключении, она форматируется с использованием formatException() и добавляется к сообщению. Обратите внимание, что отформатированная информация об исключении кэшируется в атрибуте exc_text. Это полезно, потому что информация об исключении может быть обработана и отправлена по сети, но вы должны быть осторожны, если у вас более одного подкласса Formatter, который настраивает форматирование информации об исключении. В этом случае вам нужно будет очистить кешированное значение после того, как форматтер выполнит своё форматирование, чтобы следующий форматтер для обработки события не использовало кешированное значение, а заново вычисляло его.

Если доступна информация из стека, она добавляется после информации об исключении, используя formatStack() для её преобразования, если это необходимо.

formatTime(record, datefmt=None)

Метод должен вызываться из format() форматтера, для тех, кому нужно использовать форматированное время. Метод можно переопределить в форматтерах для обеспечения любого требования, но основное поведение выглядит следующим образом: если указано datefmt (строка), она используется с time.strftime() для форматирования времени создания записи. В противном случае используется формат «%Y-%m-%d %H:%M:%S,uuu», где часть uuu представляет собой значение в миллисекундах, а остальные буквы соответствуют документации time.strftime(). Пример времени в этом формате: 2003-01-23 00:29:50,411. Возвращается результирующая строка.

Функция использует настраиваемую пользователем функцию для преобразования времени создания в кортеж. По умолчанию используется time.localtime(); чтобы изменить это для экземпляра форматтера, установите атрибут converter для функции с той же сигнатурой, что и time.localtime() или time.gmtime(). Чтобы изменить его для всех форматеров, например, если вы хотите, чтобы все время логирования отображалось в GMT, установите атрибут converter в классе Formatter.

Изменено в версии 3.3: Ранее формат по умолчанию был жёстко запрограммирован, как в этом примере: 2010-09-06 22:38:15,292, где часть перед запятой обрабатывается строкой формата strptime ('%Y-%m-%d %H:%M:%S'), а часть после запятой является значением в миллисекундах. Поскольку у strptime нет заполнителя формата для миллисекунд, значение миллисекунды добавляется с использованием другой строки формата, '%s,%03d' и обе строки формата жестко запрограммированы в данном методе. С изменением данные строки определены как атрибуты уровня класса, которые при желании можно переопределить на уровне экземпляра. Имена атрибутов: default_time_format (для строки формата strptime) и default_msec_format (для добавления значения миллисекунды).

formatException(exc_info)

Форматирует указанную информацию об исключении (стандартный кортеж исключений, возвращаемый sys.exc_info()) как строку. В этой реализации по умолчанию используется только traceback.print_exception(). Возвращается результирующая строка.

formatStack(stack_info)

Форматирует указанную информацию стека (строку, возвращаемую traceback.print_stack(), но с удаленной последней новой строкой) как строку. Реализация по умолчанию просто возвращает входное значение.

Filter объекты

Фильтры могут использоваться Обработчиками и Логгерами для более сложной фильтрации, чем это предусмотрено уровнями. Базовый класс фильтра разрешает только события, которые находятся ниже определенной точки в иерархии логгера. Например, фильтр, инициализированный с помощью «A.B», разрешит события, регистрируемые логгерами «A.B», «A.B.C», «A.B.C.D», «A.B.D» и т. д., но не «A.BB», «B.A.B» и т. д. Если инициализируется пустой строкой, передаются все события.

class logging.Filter(name='')

Возвращает экземпляр класса Filter. Если указан name, он именует логгер, события которого вместе со своими дочерними элементами будут разрешены фильтром. Если name — пустая строка, разрешает каждое событие.

filter(record)

Должна ли регистрироваться указанная запись? Возвращает ноль, если нет, ненулевое значение, если да. Если это будет сочтено целесообразным, запись может быть изменена этим методом на месте.

Обратите внимание, что фильтры, прикрепленные к обработчикам, просматриваются до того, как событие будет отправлено обработчиком, тогда как фильтры, прикрепленные к логгерам, проверяются всякий раз, когда логируется событие (с использованием debug(), info() и т. д.), перед отправкой события обработчикам. Это означает, что события, которые были сгенерированы потомками логгеров, не будут отфильтрованы настройкой фильтра логгера, если только фильтр не был применён к этим потомкам логгеров.

На самом деле вам не нужно создавать подкласс Filter: вы можете передать любой экземпляр, у которого есть метод filter с той же семантикой.

Изменено в версии 3.2: Вам не нужно создавать специализированные классы Filter или использовать другие классы с методом filter: вы можете использовать функцию (или другой вызываемый объект) в качестве фильтра. Логика фильтрации проверяет, есть ли объекта фильтра атрибут filter: если он есть, предполагается, что это Filter, и вызывается его метод filter(). В противном случае он считается вызываемым и вызывается с записью в качестве единственного параметра. Возвращаемое значение должно соответствовать возвращаемому filter().

Хотя фильтры используются в основном для фильтрации записей на основе более сложных критериев, чем уровни, они могут видеть каждую обрабатываемую обработчиком или логгером запись, к которой они прикреплены: это может быть полезно, если вам нужно посчитать количество обработанных записей определенным логгером или обработчиком, либо добавлялись, изменялись или удалялись атрибуты в обрабатываемом LogRecord. Очевидно, что изменение LogRecord необходимо производить с некоторой осторожностью, но он позволяет инжектировать контекстную информацию в журналы (см. Использование фильтров для передачи контекстной информации).

Объекты LogRecord

Экземпляры LogRecord создаются автоматически Logger каждый раз, когда что-то логируется, и могут создаваться вручную через makeLogRecord() (например, из обработанного события, полученного по сети).

class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)

Содержит всю информацию, относящуюся к логгируемому событию.

Первичная информация передается в msg и args, которые объединяются с использованием msg % args для создания поля message записи.

Параметры:
  • name – Имя логгера, используемого для логирования события, представленного LogRecord. Обратите внимание, что у имени всегда будет данное значение, даже если оно отправлено обработчиком, прикреплённого к другому (предок) логгеру.
  • level – Числовой уровень события логирования (один из DEBUG, INFO и т. д.) Обратите внимание, что он преобразуется в два атрибута файла LogRecord: levelno для числового значения и levelname для соответствующее название уровня.
  • pathname – Полный путь к исходному файлу, в котором был выполнен вызов журналирования.
  • lneno – Номер строки в исходном файле, в котором был сделан вызов журналирования.
  • msg – Сообщение с описанием события, возможно, форматная строка с заполнителями для переменных данных.
  • args – Переменные данные, которые нужно объединить с аргументом msg для получения описания события.
  • exc_info – Кортеж исключения с текущей информацией об исключении или None, если информация об исключении недоступна.
  • func – Имя функции или метода, из которого был вызван вызов журналирования.
  • sinfo – Текстовая строка, представляющая информацию о стеке от основания стека в текущем потоке до вызова журналирования.
getMessage()

Возвращает сообщение для экземпляра LogRecord после объединения любых предоставленных пользователем аргументов с сообщением. Если предоставленный пользователем аргумент сообщения для вызова логирования не является строкой, для него вызывается str(), чтобы преобразовать его в строку. Он позволяет использовать определяемые пользователем классы в качестве сообщений, чей метод __str__ может возвращать фактическую используемую форматную строку.

Изменено в версии 3.2: Создание LogRecord стало более настраиваемым за счёт предоставления фабрики, которая используется для создания записи. Фабрику можно установить с помощью getLogRecordFactory() и setLogRecordFactory() (см. сигнатуру фабрики).

Функция может использоваться для вставки ваших значений в LogRecord во время создания. Вы можете использовать следующий шаблон:

old_factory = logging.getLogRecordFactory()

def record_factory(*args, **kwargs):
    record = old_factory(*args, **kwargs)
    record.custom_attribute = 0xdecafbad
    return record

logging.setLogRecordFactory(record_factory)

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

Атрибуты LogRecord

У LogRecord есть ряд атрибутов, большинство из которых являются производными от параметров конструктора. (Обратите внимание, что имена не всегда точно соответствуют параметрам конструктора LogRecord и атрибутам LogRecord.) Эти атрибуты можно использовать для объединения данных из записи в форматную строку. В следующей таблице перечислены (в алфавитном порядке) имена атрибутов, их значения и соответствующий заполнитель в %-ного стиля форматной строки.

Если вы используете {}-форматирование (str.format()), вы можете использовать {attrname} в качестве заполнителя в форматной строке. Если вы используете $-форматирование (string.Template), используйте форму ${attrname}. В обоих случаях, конечно, замените attrname фактическим именем атрибута, которое вы хотите использовать.

В случае {}-форматирования вы можете указать флаги форматирования, поместив их после имени атрибута, отделив от него двоеточием. Например: заполнитель {msecs:03d} отформатирует миллисекундное значение 4 как 004. Обратитесь к документации str.format() для получения полной информации о доступных вам опциях.

Имя атрибута Формат Описание
args Вам не нужно форматировать его самостоятельно. Кортеж аргументов слитый в msg, чтобы произвести message или словарь, значения которого используются для слияния (когда есть только один аргумент, и это словарь).
asctime %(asctime)s Читаемое человеком время создания LogRecord. По умолчанию выглядит как „2003-07-08 16:49: 45,896“ (числа после запятой являются миллисекундной частью времени).
created %(created)f Время, когда LogRecord был создан (как возвращенный time.time()).
exc_info Вам не нужно форматировать его самостоятельно. Кортеж исключения (в духе sys.exc_info) или, если не произошло исключения None.
filename %(filename)s Filename части pathname.
funcName %(funcName)s Имя функции, содержащей вызов логирования.
levelname %(levelname)s Текстовый уровень логирования для сообщения ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').
levelno %(levelno)s Числовой уровень логирования для сообщения (DEBUG, INFO, WARNING, ERROR, CRITICAL).
lineno %(lineno)d Номер строки исходника, из которой был сделан вызов логирования (если доступен).
message %(message)s Зарегистрированное сообщение, вычисленное как msg %  args. Параметр устанавливается при вызове функции «Formatter.format()».
module %(module)s Модуль (часть имени filename).
msecs %(msecs)d
Миллисекундная часть времени создания
LogRecord.
msg Вам не нужно форматировать его самостоятельно. Форматная строка переданная в исходном вызове логирования. Слитый с args, чтобы произвести message или произвольный объект (см. Использование произвольных объектов в качестве сообщений).
name %(name)s Имя логгера используемого для логирования вызова.
pathname %(pathname)s Полное имя пути к исходному файлу, в котором был выполнен вызов логирования (если доступно).
process %(process)d ID процесса (если доступен).
processName %(processName)s Имя процесса (если доступен).
relativeCreated %(relativeCreated)d Время в миллисекундах при создании LogRecord относительно времени загрузки модуля logging.
stack_info Вам не нужно форматировать это самостоятельно. Информация о стековом фрейме (если таковая имеется) из нижней части стека в текущем потоке, вплоть до стекового фрейма вызова логирования, который привёл к созданию этой записи.
thread %(thread)d ID потока (если доступен).
threadName %(threadName)s Имя потока (если доступно).

Изменено в версии 3.1: Был добавлен processName.

Объекты LoggerAdapter

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

class logging.LoggerAdapter(logger, extra)

Возвращает экземпляр LoggerAdapter, инициализированный базовым экземпляром Logger и dict-подобным объектом.

process(msg, kwargs)

Изменяет сообщение и/или ключевые аргументы, переданные вызову логирования, чтобы вставить контекстную информацию. Реализация принимает объект, переданный как extra, в конструктор и добавляет его в kwargs с помощью ключа extra. Возвращаемое значение — кортеж (msg, kwargs), у которого есть (возможно, измененные) версии переданных аргументов.

В дополнение к вышесказанному, LoggerAdapter поддерживает следующие методы: Logger: debug(), info(), warning(), error(), exception(), critical(), log(), isEnabledFor(), getEffectiveLevel() и У данных методов те же сигнатуры, что и их аналоги в :class:`Logger(), поэтому вы можете использовать оба типа экземпляров как взаимозаменяемые.

Изменено в версии 3.2: В LoggerAdapter добавлены методы isEnabledFor(), getEffectiveLevel(), setLevel() и hasHandlers(). Методы делегируются базовому логгеру.

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

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

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

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

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

logging.getLogger(name=None)

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

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

logging.getLoggerClass()

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

class MyLogger(logging.getLoggerClass()):
    # ... переопределить здесь поведение
logging.getLogRecordFactory()

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

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

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

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

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

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

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

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

Stack (most recent call last):

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

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

FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning('Protocol problem: %s', 'connection reset', extra=d)

напечатал бы что-то вроде:

2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset

Ключи в словаре, переданном в extra, не должны конфликтовать с ключами, используемыми системой логирования. (См. документацию Formatter для получения дополнительной информации о том, какие ключи используются системой logging.)

Если вы решите использовать эти атрибуты в логгируемых сообщениях, вам нужно проявить некоторую осторожность. В приведенном выше примере, например, Formatter был настроен со форматной строкой, которая ожидает «clientip» и «user» в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет зарегистрировано, поскольку возникнет исключение форматирования строки. Таким образом, в этом случае вам всегда нужно передавать словарь extra с этими ключами.

Хотя это может раздражать, функция предназначена для использования в особых обстоятельствах, таких как многопоточные серверы, на которых один и тот же код выполняется во многих контекстах, и возникающие интересные условия зависят от этого контекста (например, IP-адрес удаленного клиента и аутентификация имя пользователя, в приведенном выше примере). В таких обстоятельствах вполне вероятно, что специализированные Formatterы будут использоваться с Handlerами.

Изменено в версии 3.2: Добавлен параметр stack_info.

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

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

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

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

Примечание

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

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

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

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

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

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

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

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

Регистрирует сообщение с уровнем level в корневом логгере. Остальные аргументы интерпретируются как debug().

Примечание

Вышеуказанные удобные функции уровня модуля, которые делегируют корневой логгер, вызывают basicConfig(), чтобы убедиться, что доступен хотя бы один обработчик. Из-за этого они не должны использоваться в потоках в версиях Python ранее, чем 2.7.1 и 3.2, если хотя бы один обработчик не был добавлен корневому логгеру перед запуском потоков. В более ранних версиях Python из-за недостатка безопасности потоков в basicConfig(), это может (в редких случаях) приводить к тому, что обработчики добавляются несколько раз к корневому логгеру, что, в свою очередь, может привести к нескольким сообщениям для одного и того же события.

logging.disable(level=CRITICAL)

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

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

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

logging.addLevelName(level, levelName)

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

Примечание

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

logging.getLevelName(level)

Возвращает текстовое представление уровня ведения журнала level. Если уровень является одним из предопределенных уровней CRITICAL, ERROR, WARNING, INFO или DEBUG, вы получаете соответствующую строку. Если вы связали уровни с именами с помощью addLevelName(), то возвращается имя, связанное с level. Если передается числовое значение, соответствующее одному из определенных уровней, возвращается соответствующее строковое представление. В противном случае возвращается строка «Level %s» % level.

Примечание

Уровни внутренне целочисленные (т. к. их нужно сравнивать в логике логирования). Функция используется для преобразования между целочисленным уровнем и именем уровня, отображаемым в форматированных выводах журнала, с помощью спецификатора формата %(levelname)s (см. Атрибуты LogRecord).

Изменено в версии 3.4: В версиях Python до 3.4 этой функции также можно было передавать текстовый уровень, и она возвращала бы соответствующее числовое значение уровня. Это недокументированное поведение было сочтено ошибкой и было удалено в Python 3.4, но восстановлено в 3.4.2 из-за сохранения обратной совместимости.

logging.makeLogRecord(attrdict)

Создаёт и возвращает новый экземпляр LogRecord, атрибуты которого определены attrdict. Функция полезна для получения пикленного словаря атрибутов LogRecord, отправленного через сокет, и восстановления его как экземпляра LogRecord на принимающей стороне.

logging.basicConfig(**kwargs)

Выполняет базовую конфигурацию для системы логирования, создавая StreamHandler с Formatter по умолчанию и добавляя его к корневому логгеру. Функции debug(), info(), warning(), error() и critical() будут вызывать basicConfig() автоматически, если для корневого логгера не определены обработчики.

Функция ничего не делает, если у корневого логгера уже настроены обработчики, если только для ключевого аргумента force не задано значение True.

Примечание

Функция должна вызываться из основного потока до того, как будут запущены другие потоки. В версиях Python до 2.7.1 и 3.2, если функция вызывается из нескольких потоков, возможно (в редких случаях), что обработчик будет добавлен к корневому логгеру более одного раза, что приведёт к неожиданным результатам, таким как дублирование сообщений в журнале.

Поддерживаются следующие ключевые аргументы.

Формат Описание
filename Указывает, что FileHandler должен создаваться с использованием указанного имени файла, а не StreamHandler.
filemode Если filename определен, открыть файл в данном режиме. По умолчанию используется значение 'a'.
format Использовать указанную форматную строку для обработчика.
datefmt Использовать указанный формат даты и времени, принятый time.strftime().
style Если задан параметр format, использовать этот стиль для форматной строки. Один из '%', '{' или '$' для printf-стиль, str.format() или string.Template соответственно. По умолчанию используется значение '%'.
level Установить уровень корневого логгера на указанный уровень.
stream Использовать указанный поток для инициализации StreamHandler. Обратите внимание, что этот аргумент несовместим с filename — если присутствуют оба, вызывается ValueError.
handlers Если указан, он должен быть итератором уже созданных обработчиков для добавления к корневому логгеру. Любые обработчики, которым не установлен форматтер, назначается форматтер по умолчанию, созданное в этой функции. Обратите внимание, что этот аргумент несовместим с filename или stream — если они присутствуют, вызывается ValueError.
force Если данный ключевой аргумент указан как true, все существующие обработчики, присоединенные к корневому логгеру, удаляются и закрываются перед выполнением конфигурации, указанной другими аргументами.

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

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

Изменено в версии 3.8: Был добавлен аргумент force.

logging.shutdown()

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

Когда модуль logging импортируется, он регистрирует эту функцию как обработчик выхода (см. atexit), поэтому обычно нет необходимости делать это вручную.

logging.setLoggerClass(klass)

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

logging.setLogRecordFactory(factory)

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

Параметры:factory – вызываемая фабрика, которая будет использоваться для создания экземпляра записи журнала.

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

У фабрики следующая сигнатура:

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

name:Имя логгера.
level:Уровень ведения журнала (числовой).
fn:Полный путь к файлу, в который был сделан вызов журналирования.
lno:Номер строки в файле, где был сделан вызов журналирования.
msg:Сообщение журнала.
args:Аргументы для сообщения журналирования.
exc_info:Кортеж исключений или None.
func:Имя функции или метода, которая вызвала logging.
sinfo:Трассировка стека, такая как предоставляется traceback.print_stack(), показывая иерархию вызовов.
kwargs:Дополнительные ключевые аргументы.

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

logging.lastResort

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

Добавлено в версии 3.2.

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

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

logging.captureWarnings(capture)

Функция используется для включения и выключения сбора предупреждений при входе и выходе.

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

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

См.также

Модуль logging.config
API конфигурации для модуля logging.
Модуль logging.handlers
Полезные обработчики, включенные в модуль logging.
PEP 282 — Система логирования
Предложение, рассказывающее о функции для включения в стандартную Python библиотеку.
Оригинальный пакет logging Python
Исходный код пакета logging. Версия пакета, доступная на этом сайте, подходит для использования с Python 1.5.2, 2.1.x и 2.2.x, которые не включают пакет logging в стандартную библиотеку.