Документация Python неофициальный перевод

logging.md

652 строк · 93.2 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.5/library/logging.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 16.6. [`logging`](https://python-all.ru/3.5/library/logging.html#module-logging) – Средство логирования для Python89**Исходный код:** [Lib/logging/\_\_init\_\_.py](https://python-all.ru/src/3.5/Lib/logging/__init__.py)1011Важно1213На этой странице содержится справочная информация по API. Обучающую информацию и обсуждение более сложных тем см. в1415- [Базовое руководство](https://python-all.ru/3.5/howto/logging.html#logging-basic-tutorial)16- [Продвинутое руководство](https://python-all.ru/3.5/howto/logging.html#logging-advanced-tutorial)17- [Поваренная книга по логированию](https://python-all.ru/3.5/howto/logging-cookbook.html#logging-cookbook)1819---2021Этот модуль определяет функции и классы, реализующие гибкую систему логирования событий для приложений и библиотек.2223Основное преимущество наличия API логирования, предоставляемого модулем стандартной библиотеки, заключается в том, что все модули Python могут участвовать в логировании, поэтому журнал вашего приложения может включать ваши собственные сообщения вместе с сообщениями от сторонних модулей.2425Модуль предоставляет множество функций и гибкость. Если вы не знакомы с логированием, лучше всего начать с учебных пособий (ссылки справа).2627Ниже перечислены основные классы модуля и их функции.2829- Регистраторы предоставляют интерфейс, который напрямую используется кодом приложения.30- Обработчики отправляют записи журнала (созданные регистраторами) в соответствующее назначение.31- Фильтры предоставляют более детальный механизм для определения того, какие записи журнала выводить.32- Форматировщики определяют расположение записей журнала в конечном выводе.3334## 16.6.1. Объекты Logger3536Логгеры имеют следующие атрибуты и методы. Обратите внимание, что логгеры никогда не создаются напрямую, а всегда через функцию уровня модуля `logging.getLogger(name)`. Многократные вызовы [`getLogger()`](https://python-all.ru/3.5/library/logging.html#logging.getLogger) с одним и тем же именем всегда возвращают ссылку на один и тот же объект Logger.3738Значение `name` потенциально является иерархическим, разделённым точками, например `foo.bar.baz` (хотя это может быть и просто `foo`). Логгеры, находящиеся ниже в иерархическом списке, являются дочерними по отношению к логгерам, находящимся выше. Например, если есть логгер с именем `foo`, то логгеры с именами `foo.bar`, `foo.bar.baz` и `foo.bam` – все являются потомками `foo`. Иерархия имён логгеров аналогична иерархии пакетов Python и совпадает с ней, если организовать логгеры по модулям, используя рекомендуемую конструкцию `logging.getLogger(__name__)`. Это потому, что в модуле `__name__` – это имя модуля в пространстве имён пакетов Python.3940#### `class logging.Logger`4142#### `Logger.propagate`4344Если это значение истинно, события, записанные в этот логгер, будут передаваться обработчикам логгеров вышестоящего уровня (родительских логгеров) в дополнение к любым обработчикам, присоединённым к этому логгеру. Сообщения передаются напрямую обработчикам родительских логгеров – ни уровень, ни фильтры этих родительских логгеров не учитываются.4546Если это ложно, сообщения логирования не передаются обработчикам логгеров-предков.4748Конструктор устанавливает этот атрибут в `True`.4950> **Примечание**51>52> Если вы прикрепите обработчик к логгеру *и* к одному или нескольким его предкам, он может выдать одну и ту же запись несколько раз. В общем случае нет необходимости прикреплять обработчик к более чем одному логгеру – если прикрепить его к соответствующему логгеру, который находится выше всех в иерархии логгеров, то он будет видеть все события, записанные всеми дочерними логгерами, при условии, что их параметр propagate оставлен равным `True`. Обычная практика – прикреплять обработчики только к корневому логгеру и позволить распространению заботиться об остальном.5354#### `Logger.setLevel(lvl)`5556Устанавливает порог для этого логгера в значение *lvl*. Сообщения логирования, которые менее важны, чем *lvl*, будут игнорироваться. При создании логгера уровень устанавливается в `NOTSET` (что приводит к обработке всех сообщений, если логгер является корневым логгером, или к делегированию родительскому логгеру, если логгер не является корневым). Обратите внимание, что корневой логгер создаётся с уровнем `WARNING`.5758Термин «делегирование родительскому регистратору» означает, что если у регистратора уровень NOTSET, то просматривается цепочка его регистраторов-предков, пока не будет найден предок с уровнем, отличным от NOTSET, или не будет достигнут корень.5960Если найден предок с уровнем, отличным от NOTSET, то его уровень считается действующим уровнем регистратора, с которого начался поиск предка, и используется для определения обработки события логирования.6162Если достигнут корень и его уровень NOTSET, то будут обработаны все сообщения. В противном случае уровень корня будет использоваться как действующий уровень.6364Список уровней см. в [Уровни логирования](https://python-all.ru/3.5/library/logging.html#levels).6566Изменено в версии 3.2: Параметр *lvl* теперь принимает строковое представление уровня, например 'INFO', в качестве альтернативы целочисленным константам таким как `INFO`. Однако обратите внимание, что уровни внутри хранятся как целые числа, и такие методы, как например [`getEffectiveLevel()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.getEffectiveLevel) и [`isEnabledFor()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.isEnabledFor), возвращают/ожидают передачи целых чисел.6768#### `Logger.isEnabledFor(lvl)`6970Указывает, будет ли сообщение с уровнем серьезности *lvl* обработано этим логгером. Этот метод сначала проверяет уровень, установленный на уровне модуля с помощью `logging.disable(lvl)`, а затем – эффективный уровень логгера, определяемый [`getEffectiveLevel()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.getEffectiveLevel).7172#### `Logger.getEffectiveLevel()`7374Указывает действующий уровень для этого регистратора. Если с помощью [`setLevel()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.setLevel) было установлено значение, отличное от `NOTSET`, возвращается оно. В противном случае иерархия просматривается в сторону корня, пока не будет найдено значение, отличное от `NOTSET`, и возвращается оно. Возвращаемое значение – целое число, обычно одно из `logging.DEBUG`, `logging.INFO` и т.д.7576#### `Logger.getChild(suffix)`7778Возвращает регистратор, который является потомком данного регистратора в соответствии с суффиксом. Таким образом, `logging.getLogger('abc').getChild('def.ghi')` вернёт тот же регистратор, что и `logging.getLogger('abc.def.ghi')`. Это удобный метод, полезный, когда родительский регистратор именуется, например, через `__name__`, а не литеральной строкой.7980Новое в версии 3.2.8182#### `Logger.debug(msg, *args, **kwargs)`8384Регистрирует сообщение с уровнем `DEBUG` в этом регистраторе. *msg* – это строка формата сообщения, а *args* – аргументы, которые объединяются в *msg* с помощью оператора форматирования строк. (Обратите внимание: это означает, что можно использовать ключевые слова в строке формата вместе с одним аргументом-словарём.)8586В *kwargs* проверяются три именованных аргумента: *exc\_info*, *stack\_info* и *extra*.8788Если *exc\_info* не равно false, к сообщению лога добавляется информация об исключении. Если предоставлен кортеж исключения (в формате, возвращаемом [`sys.exc_info()`](https://python-all.ru/3.5/library/sys.html#sys.exc_info)) или экземпляр исключения, используется он; в противном случае вызывается [`sys.exc_info()`](https://python-all.ru/3.5/library/sys.html#sys.exc_info) для получения информации об исключении.8990Второй необязательный именованный аргумент – *stack\_info*, по умолчанию `False`. Если true, к сообщению лога добавляется информация о стеке, включая сам вызов логирования. Обратите внимание, что это не та же информация о стеке, что отображается при указании *exc\_info*: первая – это кадры стека от низа стека до вызова логирования в текущем потоке, тогда как вторая – информация о кадрах стека, которые были размотаны после исключения в процессе поиска обработчиков исключений.9192Можно указать *stack\_info* независимо от *exc\_info*, например, чтобы просто показать, как был достигнут определённый участок кода, даже если исключения не возникали. Кадры стека выводятся после строки заголовка, которая гласит:9394```python95Stack (most recent call last):96```9798Это имитирует `Traceback (most recent call last):`, используемый при отображении кадров исключения.99100Третий именованный аргумент – *extra*, который можно использовать для передачи словаря, который заполняет \_\_dict\_\_ объекта LogRecord, созданного для события журналирования, пользовательскими атрибутами. Затем эти пользовательские атрибуты можно использовать по своему усмотрению. Например, их можно включать в журналируемые сообщения. Например:101102```python103FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'104logging.basicConfig(format=FORMAT)105d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}106logger = logging.getLogger('tcpserver')107logger.warning('Protocol problem: %s', 'connection reset', extra=d)108```109110выведет что-то вроде111112```python1132006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset114```115116Ключи в словаре, переданном в *extra*, не должны совпадать с ключами, используемыми системой логирования. (См. документацию [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) для получения дополнительной информации о том, какие ключи используются системой логирования.)117118Если вы решите использовать эти атрибуты в логируемых сообщениях, необходимо соблюдать осторожность. В приведённом выше примере, например, [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) настроен с форматной строкой, которая ожидает ключи ‘clientip’ и ‘user’ в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет записано, так как возникнет исключение форматирования строки. Поэтому в данном случае необходимо всегда передавать словарь *extra* с этими ключами.119120Хотя это может раздражать, эта функция предназначена для использования в специализированных ситуациях, например, в многопоточных серверах, где один и тот же код выполняется во многих контекстах, а интересующие условия зависят от этого контекста (такие как IP-адрес удаленного клиента и имя аутентифицированного пользователя в приведенном выше примере). В таких обстоятельствах, скорее всего, специализированные [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter)s будут использоваться с определенными `Handler`s.121122Новое в версии 3.2: Был добавлен параметр *stack\_info*.123124Изменено в версии 3.5: Параметр *exc\_info* теперь может принимать экземпляры исключений.125126#### `Logger.info(msg, *args, **kwargs)`127128Записывает сообщение с уровнем `INFO` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).129130#### `Logger.warning(msg, *args, **kwargs)`131132Записывает сообщение с уровнем `WARNING` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).133134> **Примечание**135>136> Существует устаревший метод `warn`, который функционально идентичен `warning`. Поскольку `warn` устарел, не используйте его – используйте `warning`.137138#### `Logger.error(msg, *args, **kwargs)`139140Записывает сообщение с уровнем `ERROR` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).141142#### `Logger.critical(msg, *args, **kwargs)`143144Записывает сообщение с уровнем `CRITICAL` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).145146#### `Logger.log(lvl, msg, *args, **kwargs)`147148Записывает сообщение с целочисленным уровнем *lvl* в этот логгер. Остальные аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).149150#### `Logger.exception(msg, *args, **kwargs)`151152Записывает сообщение с уровнем `ERROR` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug). К сообщению добавляется информация об исключении. Этот метод следует вызывать только из обработчика исключений.153154#### `Logger.addFilter(filt)`155156Добавляет указанный фильтр *filt* к этому логгеру.157158#### `Logger.removeFilter(filt)`159160Удаляет указанный фильтр *filt* из этого логгера.161162#### `Logger.filter(record)`163164Применяет фильтры этого логгера к записи и возвращает истинное значение, если запись должна быть обработана. Фильтры опрашиваются по очереди, пока один из них не вернет ложное значение. Если ни один из них не вернет ложное значение, запись будет обработана (передана обработчикам). Если какой-либо фильтр возвращает ложное значение, дальнейшая обработка записи не выполняется.165166#### `Logger.addHandler(hdlr)`167168Добавляет указанный обработчик *hdlr* к этому логгеру.169170#### `Logger.removeHandler(hdlr)`171172Удаляет указанный обработчик *hdlr* из этого логгера.173174#### `Logger.findCaller(stack_info=False)`175176Находит исходное имя файла и номер строки вызывающего кода. Возвращает имя файла, номер строки, имя функции и информацию о стеке в виде кортежа из 4 элементов. Информация о стеке возвращается как `None`, если *stack\_info* не равно `True`.177178#### `Logger.handle(record)`179180Обрабатывает запись, передавая её всем обработчикам, связанным с этим регистратором и его предками (пока не встретится ложное значение *propagate*). Этот метод используется для распакованных записей, полученных через сокет, а также для созданных локально. Фильтрация на уровне регистратора применяется с помощью [`filter()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.filter).181182#### `Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)`183184Это фабричный метод, который можно переопределить в подклассах для создания специализированных экземпляров [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord).185186#### `Logger.hasHandlers()`187188Проверяет, есть ли у этого регистратора настроенные обработчики. Это делается путём поиска обработчиков в этом регистраторе и его родителях в иерархии регистраторов. Возвращает `True`, если обработчик найден, иначе `False`. Метод прекращает поиск вверх по иерархии, как только будет найден регистратор, у которого атрибут 'propagate' установлен в false – это будет последний регистратор, проверяемый на наличие обработчиков.189190Новое в версии 3.2.191192## 16.6.2. Уровни логирования193194Числовые значения уровней журналирования приведены в следующей таблице. Они представляют интерес в первую очередь, если вы хотите определить собственные уровни и хотите, чтобы они имели определенные значения относительно предопределенных уровней. Если вы определяете уровень с тем же числовым значением, он перезаписывает предопределенное значение; предопределенное имя теряется.195196| Уровень | Числовое значение |197| --- | --- |198| `CRITICAL` | 50 |199| `ERROR` | 40 |200| `WARNING` | 30 |201| `INFO` | 20 |202| `DEBUG` | 10 |203| `NOTSET` | 0 |204205## 16.6.3. Объекты Handler206207Обработчики имеют следующие атрибуты и методы. Обратите внимание, что `Handler` никогда не создаётся напрямую; этот класс служит базой для более полезных подклассов. Однако метод [`__init__()`](https://python-all.ru/3.5/reference/datamodel.html#object.__init__) в подклассах должен вызывать [`Handler.__init__()`](https://python-all.ru/3.5/library/logging.html#logging.Handler.__init__).208209#### `Handler.__init__(level=NOTSET)`210211Инициализирует экземпляр `Handler`, устанавливая его уровень, устанавливая список фильтров в пустой список и создавая блокировку (с помощью [`createLock()`](https://python-all.ru/3.5/library/logging.html#logging.Handler.createLock)) для сериализации доступа к механизму ввода-вывода.212213#### `Handler.createLock()`214215Инициализирует блокировку потока, которую можно использовать для сериализации доступа к нижележащей функциональности ввода-вывода, которая может не быть потокобезопасной.216217#### `Handler.acquire()`218219Захватывает блокировку потока, созданную с помощью [`createLock()`](https://python-all.ru/3.5/library/logging.html#logging.Handler.createLock).220221#### `Handler.release()`222223Освобождает блокировку потока, захваченную с помощью [`acquire()`](https://python-all.ru/3.5/library/logging.html#logging.Handler.acquire).224225#### `Handler.setLevel(lvl)`226227Устанавливает порог для этого обработчика в значение *lvl*. Сообщения логирования, которые менее важны, чем *lvl*, будут игнорироваться. При создании обработчика уровень устанавливается в `NOTSET` (что приводит к обработке всех сообщений).228229Список уровней см. в [Уровни логирования](https://python-all.ru/3.5/library/logging.html#levels).230231Изменено в версии 3.2: Параметр *lvl* теперь принимает строковое представление уровня, например 'INFO', в качестве альтернативы целочисленным константам таким как `INFO`.232233#### `Handler.setFormatter(form)`234235Устанавливает [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) для данного обработчика в *форматтер*.236237#### `Handler.addFilter(filt)`238239Добавляет указанный фильтр *фильтр* в данный обработчик.240241#### `Handler.removeFilter(filt)`242243Удаляет указанный фильтр *фильтр* из данного обработчика.244245#### `Handler.filter(record)`246247Применяет фильтры этого обработчика к записи и возвращает истинное значение, если запись должна быть обработана. Фильтры опрашиваются по очереди, пока один из них не вернет ложное значение. Если ни один из них не вернет ложное значение, запись будет отправлена. Если какой-либо фильтр возвращает ложное значение, обработчик не будет отправлять запись.248249#### `Handler.flush()`250251Обеспечивает сброс всего вывода логирования. Данная версия ничего не делает и предназначена для реализации в подклассах.252253#### `Handler.close()`254255Освобождает все ресурсы, используемые обработчиком. Данная версия не выводит ничего, но удаляет обработчик из внутреннего списка обработчиков, который закрывается при вызове [`shutdown()`](https://python-all.ru/3.5/library/logging.html#logging.shutdown). Подклассы должны обеспечить вызов этого метода из переопределённых методов [`close()`](https://python-all.ru/3.5/library/logging.html#logging.Handler.close).256257#### `Handler.handle(record)`258259Условно выдает указанную запись логирования в зависимости от фильтров, которые могут быть добавлены к обработчику. Оборачивает фактическую выдачу записи в захват/освобождение блокировки потока ввода-вывода.260261#### `Handler.handleError(record)`262263Этот метод должен вызываться из обработчиков при возникновении исключения во время вызова [`emit()`](https://python-all.ru/3.5/library/logging.html#logging.Handler.emit). Если атрибут уровня модуля `raiseExceptions` равен `False`, исключения молча игнорируются. Это обычно и нужно для системы логирования – большинство пользователей не заботятся об ошибках в системе логирования, их больше интересуют ошибки приложения. Однако при желании можно заменить этот метод собственным обработчиком. Указанная запись – та, что обрабатывалась в момент возникновения исключения. (Значение по умолчанию для `raiseExceptions``True`, так как это полезнее во время разработки.)264265#### `Handler.format(record)`266267Форматирует запись – если задан форматировщик, использует его. В противном случае использует форматировщик по умолчанию для модуля.268269#### `Handler.emit(record)`270271Делает всё необходимое для фактической записи указанной записи логирования. Эта версия предназначена для реализации в подклассах и поэтому возбуждает [`NotImplementedError`](https://python-all.ru/3.5/library/exceptions.html#NotImplementedError).272273Список стандартных обработчиков см. в [`logging.handlers`](https://python-all.ru/3.5/library/logging.handlers.html#module-logging.handlers).274275## 16.6.4. Объекты Formatter276277Объекты [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) имеют следующие атрибуты и методы. Они отвечают за преобразование [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord) (обычно) в строку, которая может быть интерпретирована человеком или внешней системой. Базовый [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) позволяет задать форматирующую строку. Если она не указана, используется значение по умолчанию `'%(message)s'`, которое просто включает сообщение из вызова логирования. Чтобы добавить дополнительные элементы информации в форматированный вывод (например, временную метку), читайте дальше.278279Formatter можно инициализировать строкой форматирования, которая использует знание атрибутов [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord) – например, упомянутое выше значение по умолчанию, основанное на том, что сообщение пользователя и аргументы предварительно форматируются в атрибут *message* объекта [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord). Эта строка форматирования содержит стандартные ключи отображения в стиле % языка Python. Дополнительную информацию о форматировании строк см. в разделе [printf-style String Formatting](https://python-all.ru/3.5/library/stdtypes.html#old-string-formatting).280281Полезные ключи отображения в [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord) приведены в разделе [LogRecord attributes](https://python-all.ru/3.5/library/logging.html#logrecord-attributes).282283#### `class logging.Formatter(fmt=None, datefmt=None, style='%')`284285Возвращает новый экземпляр класса [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter). Экземпляр\\nинициализируется строкой формата для всего сообщения, а также\\nстрокой формата для части сообщения, содержащей дату/время. Если *формат* не указан,\\nиспользуется `'%(message)s'`. Если *формат даты* не указан, используется\\nформат даты ISO8601.286287Параметр *style* может быть одним из ‘%’, ‘{’ или ‘$’ и определяет, как строка форматирования будет объединена с данными: с использованием %-форматирования, [`str.format()`](https://python-all.ru/3.5/library/stdtypes.html#str.format) или [`string.Template`](https://python-all.ru/3.5/library/string.html#string.Template). См. [Использование определённых стилей форматирования в приложении](https://python-all.ru/3.5/howto/logging-cookbook.html#formatting-styles) для получения дополнительной информации об использовании {- и $-форматирования для сообщений лога.288289Изменено в версии 3.2: Добавлен параметр *style*.290291#### `format(record)`292293Словарь атрибутов записи используется как операнд для операции форматирования строки. Возвращает результирующую строку. Перед форматированием словаря выполняется несколько подготовительных шагов. Атрибут *message* записи вычисляется с помощью *msg* % *args*. Если строка форматирования содержит `'(asctime)'`, вызывается [`formatTime()`](https://python-all.ru/3.5/library/logging.html#logging.Formatter.formatTime) для форматирования времени события. Если есть информация об исключении, она форматируется с помощью [`formatException()`](https://python-all.ru/3.5/library/logging.html#logging.Formatter.formatException) и добавляется к сообщению. Обратите внимание, что отформатированная информация об исключении кэшируется в атрибуте *exc\_text*. Это полезно, поскольку информацию об исключении можно сериализовать и передавать по сети, но следует быть осторожным, если имеется более одного подкласса [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter), который настраивает форматирование информации об исключении. В этом случае придётся очищать кэшированное значение после того, как форматер выполнит своё форматирование, чтобы следующий форматер, обрабатывающий событие, не использовал кэшированное значение, а пересчитал его заново.294295Если доступна информация о стеке, она добавляется после информации об исключении с использованием [`formatStack()`](https://python-all.ru/3.5/library/logging.html#logging.Formatter.formatStack) для её преобразования, если необходимо.296297#### `formatTime(record, datefmt=None)`298299Этот метод должен вызываться из [`format()`](https://python-all.ru/3.5/library/functions.html#format) форматтером, который\\nхочет использовать форматированное время. Этот метод можно переопределить в\\nформаттерах для удовлетворения любых конкретных требований, но базовое поведение\\nтаково: если указан *формат даты* (строка), он используется с\\n[`time.strftime()`](https://python-all.ru/3.5/library/time.html#time.strftime) для форматирования времени создания\\nзаписи. В противном случае используется формат ISO8601. Результирующая строка\\nвозвращается.300301Эта функция использует настраиваемую пользователем функцию для преобразования времени создания в кортеж. По умолчанию используется [`time.localtime()`](https://python-all.ru/3.5/library/time.html#time.localtime); чтобы изменить это для конкретного экземпляра форматтера, установите атрибут `converter` на функцию с той же сигнатурой, что и [`time.localtime()`](https://python-all.ru/3.5/library/time.html#time.localtime) или [`time.gmtime()`](https://python-all.ru/3.5/library/time.html#time.gmtime). Чтобы изменить это для всех форматтеров, например, если вы хотите показывать все времена логирования в GMT, установите атрибут `converter` в классе `Formatter`.302303Изменено в версии 3.3: Ранее формат ISO 8601 по умолчанию был жёстко задан, как в этом\\nпримере: `2010-09-06 22:38:15,292` где часть до запятой\\nобрабатывается строкой форматирования (`'%Y-%m-%d %H:%M:%S'`), а\\nчасть после запятой – значение в миллисекундах. Поскольку strptime не\\nимеет заполнителя для миллисекунд, значение миллисекунд\\nдобавляется с помощью другой строки форматирования, `'%s,%03d'` – и обе эти\\nстроки форматирования были жёстко закодированы в этом методе. С изменением\\nэти строки определяются как атрибуты уровня класса, которые можно\\nпереопределить на уровне экземпляра при необходимости. Имена\\nатрибутов: `default_time_format` (для строки форматирования)\\nи `default_msec_format` (для добавления значения миллисекунд).304305#### `formatException(exc_info)`306307Форматирует указанную информацию об исключении (стандартный кортеж исключения, возвращаемый [`sys.exc_info()`](https://python-all.ru/3.5/library/sys.html#sys.exc_info)) в строку. Эта реализация по умолчанию просто использует [`traceback.print_exception()`](https://python-all.ru/3.5/library/traceback.html#traceback.print_exception). Возвращается результирующая строка.308309#### `formatStack(stack_info)`310311Форматирует указанную информацию о стеке (строку, возвращаемую [`traceback.print_stack()`](https://python-all.ru/3.5/library/traceback.html#traceback.print_stack), но с удалённым последним символом новой строки) в строку. Эта реализация по умолчанию просто возвращает входное значение.312313## 16.6.5. Объекты Filter314315`Filters` могут использоваться `Handlers` и `Loggers` для более сложной фильтрации, чем та, что обеспечивается уровнями. Базовый класс фильтра пропускает только события, которые находятся ниже определённой точки в иерархии логгеров. Например, фильтр, инициализированный строкой 'A.B', будет пропускать события, записанные логгерами 'A.B', 'A.B.C', 'A.B.C.D', 'A.B.D' и т.д., но не 'A.BB', 'B.A.B' и т.д. Если инициализирован пустой строкой, пропускаются все события.316317#### `class logging.Filter(name='')`318319Возвращает экземпляр класса [`Filter`](https://python-all.ru/3.5/library/logging.html#logging.Filter). Если указан *name*, он задаёт имя логгера, который вместе со своими потомками будет пропускать свои события через фильтр. Если *name* – пустая строка, пропускаются все события.320321#### `filter(record)`322323Следует ли регистрировать указанную запись? Возвращает ноль, если нет, и ненулевое значение, если да. Если это уместно, запись может быть изменена на месте данным методом.324325Обратите внимание, что фильтры, прикреплённые к обработчикам, проверяются перед тем, как событие будет отправлено обработчиком, тогда как фильтры, прикреплённые к логгерам, проверяются всякий раз, когда событие регистрируется (с помощью [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug), [`info()`](https://python-all.ru/3.5/library/logging.html#logging.info) и т.д.), перед отправкой события обработчикам. Это означает, что события, созданные дочерними логгерами, не будут отфильтрованы настройкой фильтра логгера, если только фильтр не был также применён к этим дочерним логгерам.326327Не требуется создавать подкласс `Filter`: можно передать любой экземпляр, у которого есть метод `filter` с той же семантикой.328329Изменено в версии 3.2: Не требуется создавать специализированные классы `Filter` или использовать другие классы с методом `filter`: можно использовать функцию (или другой вызываемый объект) в качестве фильтра. Логика фильтрации проверяет, есть ли у объекта фильтра атрибут `filter`: если есть, считается, что это `Filter`, и вызывается его метод [`filter()`](https://python-all.ru/3.5/library/logging.html#logging.Filter.filter). В противном случае считается, что это вызываемый объект, и он вызывается с записью в качестве единственного параметра. Возвращаемое значение должно соответствовать тому, что возвращается [`filter()`](https://python-all.ru/3.5/library/logging.html#logging.Filter.filter).330331Хотя фильтры в первую очередь используются для фильтрации записей на основе более сложных критериев, чем уровни, они видят каждую запись, которая обрабатывается обработчиком или регистратором, к которому они прикреплены: это может быть полезно, если нужно, например, подсчитать, сколько записей было обработано конкретным регистратором или обработчиком, или добавить, изменить или удалить атрибуты в обрабатываемом LogRecord. Очевидно, что изменение LogRecord требует определённой осторожности, но это позволяет внедрять контекстную информацию в журналы (см. [Использование фильтров для передачи контекстной информации](https://python-all.ru/3.5/howto/logging-cookbook.html#filters-contextual)).332333## 16.6.6. Объекты LogRecord334335Экземпляры [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord) создаются автоматически [`Logger`](https://python-all.ru/3.5/library/logging.html#logging.Logger) каждый раз, когда что-то регистрируется, и могут быть созданы вручную через [`makeLogRecord()`](https://python-all.ru/3.5/library/logging.html#logging.makeLogRecord) (например, из сериализованного события, полученного по сети).336337#### `class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)`338339Содержит всю информацию, относящуюся к регистрируемому событию.340341Основная информация передаётся через `msg` и `args`, которые объединяются с помощью `msg % args` для создания поля `message` записи.342343| Параметры: | **name** – Имя логгера, используемого для регистрации события, представленного этой LogRecord. Обратите внимание, что это имя всегда будет иметь данное значение, даже если событие может быть отправлено обработчиком, прикреплённым к другому (родительскому) логгеру. **level** – Числовой уровень события логирования (один из DEBUG, INFO и т.д.) Обратите внимание, что он преобразуется в *два* атрибута LogRecord: `levelno` для числового значения и `levelname` для соответствующего имени уровня. **pathname** – Полный путь к исходному файлу, в котором был выполнен вызов логирования. **lineno** – Номер строки в исходном файле, в которой был выполнен вызов логирования. **msg** – Описание события, возможно, строка форматирования с заполнителями для переменных данных. **args** – Переменные данные для подстановки в аргумент *msg* для получения описания события. **exc\_info** – Кортеж исключения с текущей информацией об исключении или `None`, если информация об исключении отсутствует. **func** – Имя функции или метода, из которого был выполнен вызов логирования. **sinfo** – Текстовая строка, представляющая информацию о стеке от основания стека в текущем потоке до вызова логирования. |344| --- | --- |345346#### `getMessage()`347348Возвращает сообщение для этого экземпляра [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord) после объединения любых аргументов, предоставленных пользователем, с сообщением. Если аргумент сообщения, предоставленный пользователем при вызове журналирования, не является строкой, для преобразования его в строку вызывается [`str()`](https://python-all.ru/3.5/library/stdtypes.html#str). Это позволяет использовать определённые пользователем классы в качестве сообщений, чей метод `__str__` может возвращать фактическую строку форматирования.349350Изменено в версии 3.2: Создание `LogRecord` стало более настраиваемым благодаря предоставлению фабрики, используемой для создания записи. Фабрику можно задать с помощью [`getLogRecordFactory()`](https://python-all.ru/3.5/library/logging.html#logging.getLogRecordFactory) и [`setLogRecordFactory()`](https://python-all.ru/3.5/library/logging.html#logging.setLogRecordFactory) (см. сигнатуру фабрики).351352Эту функциональность можно использовать для внедрения собственных значений в LogRecord при его создании. Можно воспользоваться следующим шаблоном:353354```python355old_factory = logging.getLogRecordFactory()356357def record_factory(*args, **kwargs):358    record = old_factory(*args, **kwargs)359    record.custom_attribute = 0xdecafbad360    return record361362logging.setLogRecordFactory(record_factory)363```364365При таком шаблоне можно объединять несколько фабрик, и пока они не перезаписывают атрибуты друг друга или случайно не перезаписывают стандартные атрибуты, перечисленные выше, сюрпризов быть не должно.366367## 16.6.7. Атрибуты LogRecord368369LogRecord имеет ряд атрибутов, большинство из которых получены из параметров конструктора. (Обратите внимание, что имена не всегда точно соответствуют между параметрами конструктора LogRecord и атрибутами LogRecord.) Эти атрибуты можно использовать для объединения данных из записи в строку форматирования. В следующей таблице перечислены (в алфавитном порядке) имена атрибутов, их значения и соответствующий заполнитель в строке форматирования в стиле %.370371Если используется форматирование {} ([`str.format()`](https://python-all.ru/3.5/library/stdtypes.html#str.format)), можно использовать `{attrname}` в качестве заполнителя в строке форматирования. Если используется форматирование $ ([`string.Template`](https://python-all.ru/3.5/library/string.html#string.Template)), используйте форму `${attrname}`. В обоих случаях, конечно, замените `attrname` на фактическое имя атрибута.372373В случае форматирования {} можно указать флаги форматирования, поместив их после имени атрибута, отделив двоеточием. Например: заполнитель `{msecs:03d}` отформатирует значение миллисекунд `4` как `004`. Обратитесь к документации [`str.format()`](https://python-all.ru/3.5/library/stdtypes.html#str.format) для получения полной информации о доступных параметрах.374375| Имя атрибута | Формат | Описание |376| --- | --- | --- |377| аргументы | Форматировать это самостоятельно не требуется. | Кортеж аргументов, объединяемых в `msg` для получения `message`, или словарь, значения которого используются для объединения (когда есть только один аргумент, и это словарь). |378| asctime | `%(asctime)s` | Время создания [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord) в удобочитаемом формате. По умолчанию оно имеет вид '2003-07-08 16:49:45,896' (цифры после запятой – миллисекундная часть времени). |379| created | `%(created)f` | Время создания [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord) (возвращается [`time.time()`](https://python-all.ru/3.5/library/time.html#time.time)). |380| exc\_info | Форматировать это самостоятельно не требуется. | Кортеж с информацией об исключении (как в `sys.exc_info`) или `None`, если исключения не было. |381| filename | `%(filename)s` | Часть имени файла из `pathname`. |382| funcName | `%(funcName)s` | Имя функции, содержащей вызов логирования. |383| levelname | `%(levelname)s` | Текстовый уровень логирования для сообщения (`'DEBUG'`, `'INFO'`, `'WARNING'`, `'ERROR'`, `'CRITICAL'`). |384| levelno | `%(levelno)s` | Числовой уровень логирования для сообщения (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`). |385| lineno | `%(lineno)d` | Номер строки исходного кода, из которой был сделан вызов логирования (если доступен). |386| модуль | `%(module)s` | Модуль (часть имени из `filename`). |387| msecs | `%(msecs)d` | Миллисекундная часть времени создания [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord). |388| message | `%(message)s` | Журналируемое сообщение, вычисляемое как `msg % args`. Задаётся при вызове [`Formatter.format()`](https://python-all.ru/3.5/library/logging.html#logging.Formatter.format). |389| msg | Форматировать это самостоятельно не требуется. | Строка формата, переданная в исходном вызове логирования. Объединяется с `args` для получения `message`, или произвольный объект (см. [Использование произвольных объектов в качестве сообщений](https://python-all.ru/3.5/howto/logging.html#arbitrary-object-messages)). |390| имя | `%(name)s` | Имя регистратора, использованного для записи вызова. |391| pathname | `%(pathname)s` | Полный путь к исходному файлу, из которого был сделан вызов логирования (если доступен). |392| процесс | `%(process)d` | Идентификатор процесса (если доступен). |393| processName | `%(processName)s` | Имя процесса (если доступно). |394| relativeCreated | `%(relativeCreated)d` | Время в миллисекундах, когда LogRecord был создан, относительно времени загрузки модуля logging. |395| stack\_info | Форматировать это самостоятельно не требуется. | Информация о стековых фреймах (где доступна) от дна стека в текущем потоке до стекового фрейма включительно, соответствующего вызову логирования, который привёл к созданию этой записи. |396| поток | `%(thread)d` | Идентификатор потока (если доступен). |397| threadName | `%(threadName)s` | Имя потока (если доступно). |398399Изменено в версии 3.1: *processName* был добавлен.400401## 16.6.8. Объекты LoggerAdapter402403Экземпляры [`LoggerAdapter`](https://python-all.ru/3.5/library/logging.html#logging.LoggerAdapter) используются для удобной передачи контекстной информации в вызовы логирования. Пример использования см. в разделе [добавления контекстной информации в вывод логирования](https://python-all.ru/3.5/howto/logging-cookbook.html#context-info).404405#### `class logging.LoggerAdapter(logger, extra)`406407Возвращает экземпляр [`LoggerAdapter`](https://python-all.ru/3.5/library/logging.html#logging.LoggerAdapter), инициализированный базовым экземпляром [`Logger`](https://python-all.ru/3.5/library/logging.html#logging.Logger) и объектом, подобным словарю.408409#### `process(msg, kwargs)`410411Изменяет сообщение и/или именованные аргументы, переданные в вызов логирования, чтобы вставить контекстную информацию. Эта реализация берёт объект, переданный как *extra* конструктору, и добавляет его в *kwargs* с ключом 'extra'. Возвращаемое значение – кортеж (*msg*, *kwargs*), содержащий (возможно изменённые) версии переданных аргументов.412413В дополнение к вышеперечисленному, [`LoggerAdapter`](https://python-all.ru/3.5/library/logging.html#logging.LoggerAdapter) поддерживает следующие методы [`Logger`](https://python-all.ru/3.5/library/logging.html#logging.Logger): [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.debug), [`info()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.info), [`warning()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.warning), [`error()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.error), [`exception()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.exception), [`critical()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.critical), [`log()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.log), [`isEnabledFor()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.isEnabledFor), [`getEffectiveLevel()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.getEffectiveLevel), [`setLevel()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.setLevel) и [`hasHandlers()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.hasHandlers). Эти методы имеют те же сигнатуры, что и их аналоги в [`Logger`](https://python-all.ru/3.5/library/logging.html#logging.Logger), поэтому можно использовать оба типа экземпляров взаимозаменяемо.414415Изменено в версии 3.2: Методы [`isEnabledFor()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.isEnabledFor), [`getEffectiveLevel()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.getEffectiveLevel), [`setLevel()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.setLevel) и [`hasHandlers()`](https://python-all.ru/3.5/library/logging.html#logging.Logger.hasHandlers) были добавлены в [`LoggerAdapter`](https://python-all.ru/3.5/library/logging.html#logging.LoggerAdapter). Эти методы делегируют выполнение базовому логгеру.416417## 16.6.9. Потокобезопасность418419Модуль logging спроектирован так, чтобы быть потокобезопасным без каких-либо специальных действий требуемых от его клиентов. Это достигается за счёт использования threading блокировок; одна блокировка сериализует доступ к общим данным модуля, а каждый обработчик также создаёт блокировку для сериализации доступа к своему нижележащему вводу-выводу.420421Если при реализации асинхронных обработчиков сигналов с помощью модуля [`signal`](https://python-all.ru/3.5/library/signal.html#module-signal) может оказаться, что использовать логирование внутри таких обработчиков невозможно. Это связано с тем, что реализации блокировок в модуле [`threading`](https://python-all.ru/3.5/library/threading.html#module-threading) не всегда реентерабельны и поэтому не могут быть вызваны из таких обработчиков сигналов.422423## 16.6.10. Функции уровня модуля424425В дополнение к классам, описанным выше, существует ряд функций уровня модуля.426427#### `logging.getLogger(name=None)`428429Возвращает логгер с указанным именем или, если name равно `None`, возвращает корневой логгер иерархии. Если имя указано, оно обычно представляет собой иерархическое имя, разделённое точками, например *'a'*, *'a.b'* или *'a.b.c.d'*. Выбор этих имен полностью зависит от разработчика, использующего логирование.430431Все вызовы этой функции с одним и тем же именем возвращают один и тот же экземпляр логгера. Это означает, что экземпляры логгера никогда не нужно передавать между различными частями приложения.432433#### `logging.getLoggerClass()`434435Возвращает либо стандартный класс [`Logger`](https://python-all.ru/3.5/library/logging.html#logging.Logger), либо последний класс, переданный в [`setLoggerClass()`](https://python-all.ru/3.5/library/logging.html#logging.setLoggerClass). Эту функцию можно вызывать из определения нового класса, чтобы гарантировать, что установка пользовательского класса [`Logger`](https://python-all.ru/3.5/library/logging.html#logging.Logger) не отменит настройки, уже применённые другим кодом. Например:436437```python438class MyLogger(logging.getLoggerClass()):439    # ... переопределить поведение здесь440```441442#### `logging.getLogRecordFactory()`443444Возвращает вызываемый объект, который используется для создания [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord).445446Новое в версии 3.2: Эта функция была добавлена вместе с [`setLogRecordFactory()`](https://python-all.ru/3.5/library/logging.html#logging.setLogRecordFactory), чтобы разработчики могли лучше контролировать создание [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord), представляющего событие логирования.447448См. [`setLogRecordFactory()`](https://python-all.ru/3.5/library/logging.html#logging.setLogRecordFactory) для получения дополнительной информации о том, как вызывается фабрика.449450#### `logging.debug(msg, *args, **kwargs)`451452Записывает сообщение с уровнем `DEBUG` в корневой регистратор. Параметр *msg* – это строка форматирования сообщения, а *args* – аргументы, которые подставляются в *msg* с помощью оператора форматирования строк. (Обратите внимание: это означает, что в строке форматирования можно использовать ключевые слова вместе с одним словарным аргументом.)453454В *kwargs* проверяются три именованных аргумента: *exc\_info* который, если не равен false, добавляет информацию об исключении в сообщение журнала. Если предоставлен кортеж исключения (в формате, возвращаемом [`sys.exc_info()`](https://python-all.ru/3.5/library/sys.html#sys.exc_info)), он используется; в противном случае [`sys.exc_info()`](https://python-all.ru/3.5/library/sys.html#sys.exc_info) вызывается для получения информации об исключении.455456Второй необязательный именованный аргумент – *stack\_info*, по умолчанию `False`. Если true, к сообщению лога добавляется информация о стеке, включая сам вызов логирования. Обратите внимание, что это не та же информация о стеке, что отображается при указании *exc\_info*: первая – это кадры стека от низа стека до вызова логирования в текущем потоке, тогда как вторая – информация о кадрах стека, которые были размотаны после исключения в процессе поиска обработчиков исключений.457458Можно указать *stack\_info* независимо от *exc\_info*, например, чтобы просто показать, как был достигнут определённый участок кода, даже если исключения не возникали. Кадры стека выводятся после строки заголовка, которая гласит:459460```python461Stack (most recent call last):462```463464Это имитирует `Traceback (most recent call last):`, используемый при отображении кадров исключения.465466Третий необязательный именованный аргумент – *extra*, с помощью которого можно передать словарь, используемый для заполнения \_\_dict\_\_ объекта LogRecord, созданного для события логирования, пользовательскими атрибутами. Затем эти пользовательские атрибуты можно использовать по своему усмотрению. Например, их можно включать в логируемые сообщения. Пример:467468```python469FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'470logging.basicConfig(format=FORMAT)471d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}472logging.warning('Protocol problem: %s', 'connection reset', extra=d)473```474475выведет что-то вроде:476477```python4782006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset479```480481Ключи в словаре, переданном в *extra*, не должны совпадать с ключами, используемыми системой логирования. (См. документацию [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) для получения дополнительной информации о том, какие ключи используются системой логирования.)482483Если вы решите использовать эти атрибуты в логируемых сообщениях, необходимо соблюдать осторожность. В приведённом выше примере, например, [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) настроен с форматной строкой, которая ожидает ключи ‘clientip’ и ‘user’ в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет записано, так как возникнет исключение форматирования строки. Поэтому в данном случае необходимо всегда передавать словарь *extra* с этими ключами.484485Хотя это может раздражать, эта функция предназначена для использования в специализированных ситуациях, например, в многопоточных серверах, где один и тот же код выполняется во многих контекстах, а интересующие условия зависят от этого контекста (такие как IP-адрес удаленного клиента и имя аутентифицированного пользователя в приведенном выше примере). В таких обстоятельствах, скорее всего, специализированные [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter)s будут использоваться с определенными `Handler`s.486487Новое в версии 3.2: Был добавлен параметр *stack\_info*.488489#### `logging.info(msg, *args, **kwargs)`490491Записывает сообщение с уровнем `INFO` в корневой регистратор. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).492493#### `logging.warning(msg, *args, **kwargs)`494495Записывает сообщение с уровнем `WARNING` в корневой регистратор. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).496497> **Примечание**498>499> Существует устаревшая функция `warn`, которая функционально идентична `warning`. Поскольку `warn` устарела, не используйте её – вместо неё используйте `warning`.500501#### `logging.error(msg, *args, **kwargs)`502503Записывает сообщение с уровнем `ERROR` в корневой регистратор. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).504505#### `logging.critical(msg, *args, **kwargs)`506507Записывает сообщение с уровнем `CRITICAL` в корневой регистратор. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).508509#### `logging.exception(msg, *args, **kwargs)`510511Записывает сообщение с уровнем `ERROR` в корневой регистратор. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug). Информация об исключении добавляется в сообщение логирования. Эту функцию следует вызывать только из обработчика исключений.512513#### `logging.log(level, msg, *args, **kwargs)`514515Записывает сообщение с уровнем *level* в корневой регистратор. Остальные аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug).516517> **Примечание**518>519> Указанные выше удобные функции уровня модуля, которые делегируют корневому регистратору, вызывают [`basicConfig()`](https://python-all.ru/3.5/library/logging.html#logging.basicConfig), чтобы гарантировать наличие хотя бы одного обработчика. Из-за этого их *не* следует использовать в потоках в версиях Python ниже 2.7.1 и 3.2, если только *до* запуска потоков в корневой регистратор не был добавлен хотя бы один обработчик. В более ранних версиях Python из-за недостатка потокобезопасности в [`basicConfig()`](https://python-all.ru/3.5/library/logging.html#logging.basicConfig) это (в редких случаях) может привести к многократному добавлению обработчиков в корневой регистратор, что в свою очередь может привести к появлению нескольких сообщений для одного и того же события.520521#### `logging.disable(lvl)`522523Устанавливает переопределяющий уровень *lvl* для всех регистраторов, который имеет приоритет над их собственным уровнем. Когда возникает необходимость временно снизить интенсивность вывода журнала во всём приложении, эта функция может быть полезной. Её действие заключается в отключении всех вызовов регистрации с серьёзностью *lvl* и ниже, так что если вызвать её со значением INFO, то все события уровня INFO и DEBUG будут отброшены, а события серьёзности WARNING и выше будут обработаны в соответствии с эффективным уровнем регистратора. Если `logging.disable(logging.NOTSET)` вызывается, это действие отменяет переопределяющий уровень, так что вывод журнала снова зависит от эффективных уровней отдельных регистраторов.524525#### `logging.addLevelName(lvl, levelName)`526527Связывает уровень *lvl* с текстом *levelName* во внутреннем словаре, который используется для сопоставления числовых уровней с текстовым представлением, например, когда [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) форматирует сообщение. Эта функция также может использоваться для определения собственных уровней. Единственное ограничение заключается в том, что все используемые уровни должны быть зарегистрированы с помощью этой функции, уровни должны быть положительными целыми числами и они должны увеличиваться в порядке возрастания серьёзности.528529> **Примечание**530>531> Если вы планируете определять собственные уровни, обратитесь к разделу [Пользовательские уровни](https://python-all.ru/3.5/howto/logging.html#custom-levels).532533#### `logging.getLevelName(lvl)`534535Возвращает текстовое представление уровня логирования *lvl*. Если уровень является одним из предопределённых уровней `CRITICAL`, `ERROR`, `WARNING`, `INFO` или `DEBUG`, то возвращается соответствующая строка. Если вы связали уровни с именами с помощью [`addLevelName()`](https://python-all.ru/3.5/library/logging.html#logging.addLevelName), то возвращается имя, которое вы связали с *lvl*. Если передано числовое значение, соответствующее одному из определённых уровней, возвращается соответствующее строковое представление. В противном случае возвращается строка 'Level %s' % lvl.536537> **Примечание**538>539> Уровни внутри представлены целыми числами (поскольку их нужно сравнивать в логике логирования). Эта функция используется для преобразования между целочисленным уровнем и названием уровня, отображаемым в форматированном выводе лога с помощью спецификатора формата `%(levelname)s` (см. [атрибуты LogRecord](https://python-all.ru/3.5/library/logging.html#logrecord-attributes)).540541Изменено в версии 3.4: В версиях Python до 3.4 этой функции также можно было передать текстовый уровень, и она возвращала соответствующее числовое значение уровня. Это недокументированное поведение считалось ошибкой и было удалено в Python 3.4, но восстановлено в 3.4.2 для сохранения обратной совместимости.542543#### `logging.makeLogRecord(attrdict)`544545Создаёт и возвращает новый экземпляр [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord), атрибуты которого определяются *attrdict*. Эта функция полезна для получения сериализованного словаря атрибутов [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord), отправленного через сокет, и восстановления его в экземпляр [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord) на принимающей стороне.546547#### `logging.basicConfig(**kwargs)`548549Выполняет базовую настройку системы логирования, создавая [`StreamHandler`](https://python-all.ru/3.5/library/logging.handlers.html#logging.StreamHandler) с [`Formatter`](https://python-all.ru/3.5/library/logging.html#logging.Formatter) по умолчанию и добавляя его в корневой логгер. Функции [`debug()`](https://python-all.ru/3.5/library/logging.html#logging.debug), [`info()`](https://python-all.ru/3.5/library/logging.html#logging.info), [`warning()`](https://python-all.ru/3.5/library/logging.html#logging.warning), [`error()`](https://python-all.ru/3.5/library/logging.html#logging.error) и [`critical()`](https://python-all.ru/3.5/library/logging.html#logging.critical) будут вызывать [`basicConfig()`](https://python-all.ru/3.5/library/logging.html#logging.basicConfig) автоматически, если для корневого логгера не определены обработчики.550551Эта функция ничего не делает, если для корневого логгера уже настроены обработчики.552553> **Примечание**554>555> Эту функцию следует вызывать из главного потока до запуска других потоков. В версиях Python до 2.7.1 и 3.2, если эта функция вызывается из нескольких потоков, в редких случаях обработчик может быть добавлен в корневой логгер более одного раза, что приводит к неожиданным результатам, например, к дублированию сообщений в логе.556557Поддерживаются следующие аргументы ключевых слов.558559| Формат | Описание |560| --- | --- |561| `filename` | Указывает, что создаётся FileHandler, с использованием указанного имени файла, а не StreamHandler. |562| `filemode` | Задает режим открытия файла, если указан filename (если filemode не указан, по умолчанию используется ‘a’). |563| `format` | Использует указанную строку формата для обработчика. |564| `datefmt` | Использовать указанный формат даты/времени. |565| `style` | Если указан `format`, используйте этот стиль для строки формата. Один из ‘%’, ‘{’ или ‘$’ для %-форматирования, [`str.format()`](https://python-all.ru/3.5/library/stdtypes.html#str.format) или [`string.Template`](https://python-all.ru/3.5/library/string.html#string.Template) соответственно, и по умолчанию ‘%’, если не указано. |566| `level` | Установить уровень корневого регистратора на указанный уровень. |567| `stream` | Использовать указанный поток для инициализации StreamHandler. Обратите внимание, что этот аргумент несовместим с ‘filename’ – если оба указаны, вызывается `ValueError`. |568| `handlers` | Если указано, это должна быть итерируемая последовательность уже созданных обработчиков для добавления к корневому регистратору. Любые обработчики, у которых еще не установлен форматтер, получат форматтер по умолчанию, созданный в этой функции. Обратите внимание, что этот аргумент несовместим с ‘filename’ или ‘поток данных’ – если оба указаны, вызывается `ValueError`. |569570Изменено в версии 3.2: Добавлен аргумент `style`.571572Изменено в версии 3.3: Добавлен аргумент `handlers`. Добавлены дополнительные проверки для выявления ситуаций, когда указаны несовместимые аргументы (например, `handlers` вместе с `stream` или `filename`, или `stream` вместе с `filename`).573574#### `logging.shutdown()`575576Сообщает системе логирования о необходимости выполнить упорядоченное завершение работы, сбрасывая и закрывая все обработчики. Эту функцию следует вызывать при завершении приложения, и после этого вызова не следует использовать систему логирования.577578#### `logging.setLoggerClass(klass)`579580Указывает системе логирования использовать класс *klass* при создании экземпляра регистратора. Класс должен определить [`__init__()`](https://python-all.ru/3.5/reference/datamodel.html#object.__init__) таким образом, чтобы требовался только аргумент name, и [`__init__()`](https://python-all.ru/3.5/reference/datamodel.html#object.__init__) должен вызывать `Logger.__init__()`. Эта функция обычно вызывается до создания экземпляров регистраторов приложениями, которым необходимо использовать пользовательское поведение регистратора.581582#### `logging.setLogRecordFactory(factory)`583584Устанавливает вызываемый объект, используемый для создания [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord).585586| Параметры: | **factory** – вызываемый объект фабрики, используемый для создания записи журнала. |587| --- | --- |588589Новое в версии 3.2: Эта функция была добавлена вместе с [`getLogRecordFactory()`](https://python-all.ru/3.5/library/logging.html#logging.getLogRecordFactory), чтобы разработчики могли лучше контролировать создание [`LogRecord`](https://python-all.ru/3.5/library/logging.html#logging.LogRecord), представляющего событие логирования.590591Фабрика имеет следующую сигнатуру:592593`factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)`594595> | имя: | Имя регистратора. |596> | --- | --- |597> | уровень: | Уровень логирования (числовой). |598> | fn: | Полный путь к файлу, в котором был выполнен вызов логирования. |599> | lno: | Номер строки в файле, в котором был выполнен вызов логирования. |600> | сообщение: | Сообщение логирования. |601> | аргументы: | Аргументы для сообщения логирования. |602> | exc\_info: | Кортеж исключения или `None`. |603> | func: | Имя функции или метода, из которого был сделан вызов логирования. |604> | sinfo: | Трассировка стека, например, предоставляемая [`traceback.print_stack()`](https://python-all.ru/3.5/library/traceback.html#traceback.print_stack), показывающая иерархию вызовов. |605> | kwargs: | Дополнительные именованные аргументы. |606607## 16.6.11. Атрибуты уровня модуля608609#### `logging.lastResort`610611«Обработчик последней надежды» доступен через этот атрибут. Он представляет собой [`StreamHandler`](https://python-all.ru/3.5/library/logging.handlers.html#logging.StreamHandler), который пишет в `sys.stderr` с уровнем `WARNING` и используется для обработки событий логирования при отсутствии какой-либо конфигурации логирования. В результате сообщение просто выводится в `sys.stderr`. Это заменяет более раннее сообщение об ошибке, гласившее, «для регистратора XYZ не найдено обработчиков». Если по какой-то причине нужно вернуть прежнее поведение, `lastResort` можно установить в `None`.612613Новое в версии 3.2.614615## 16.6.12. Интеграция с модулем warnings616617Функция [`captureWarnings()`](https://python-all.ru/3.5/library/logging.html#logging.captureWarnings) может использоваться для интеграции [`logging`](https://python-all.ru/3.5/library/logging.html#module-logging) с модулем [`warnings`](https://python-all.ru/3.5/library/warnings.html#module-warnings).618619#### `logging.captureWarnings(capture)`620621Эта функция используется для включения и выключения перехвата предупреждений системой логирования.622623Если *capture* имеет значение `True`, предупреждения, выдаваемые модулем [`warnings`](https://python-all.ru/3.5/library/warnings.html#module-warnings), будут перенаправляться в систему логирования. В частности, предупреждение будет отформатировано с помощью [`warnings.formatwarning()`](https://python-all.ru/3.5/library/warnings.html#warnings.formatwarning), и результирующая строка будет записана в регистратор с именем `'py.warnings'` с уровнем серьезности `WARNING`.624625Если *capture* имеет значение `False`, перенаправление предупреждений в систему логирования прекратится, и предупреждения будут направляться по своим исходным адресатам (т.е. тем, которые действовали до вызова `captureWarnings(True)`).626627> **См. также**628>629> **Модуль [`logging.config`](https://python-all.ru/3.5/library/logging.config.html#module-logging.config)**630>631> API конфигурации для модуля logging.632>633> **Модуль [`logging.handlers`](https://python-all.ru/3.5/library/logging.handlers.html#module-logging.handlers)**634>635> Полезные обработчики, входящие в состав модуля logging.636>637> **[**PEP 282**](https://python-all.ru/3.5/library/logging.html) – Система логирования**638>639> Предложение, описывающее эту возможность для включения в стандартную библиотеку Python.640>641> **[Оригинальный пакет логирования Python](https://python-all.ru/3.5/library/logging.html)**642>643> Это исходный код пакета644>645> [`logging`](https://python-all.ru/3.5/library/logging.html#module-logging)646>647> . Версия пакета, доступная на этом сайте, подходит для использования с Python 1.5.2, 2.1.x и 2.2.x, в которых пакет648>649> [`logging`](https://python-all.ru/3.5/library/logging.html#module-logging)650>651> не входит в стандартную библиотеку.652