logging.md
1> **Источник:** https://python-all.ru/3.4/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.4/library/logging.html#module-logging) – средство логирования для Python89Важно1011На этой странице содержится справочная информация по API. Обучающую информацию и обсуждение более сложных тем см. в1213- [*Базовое руководство*](https://python-all.ru/3.4/howto/logging.html#logging-basic-tutorial)14- [*Продвинутое руководство*](https://python-all.ru/3.4/howto/logging.html#logging-advanced-tutorial)15- [*Поваренная книга по логированию*](https://python-all.ru/3.4/howto/logging-cookbook.html#logging-cookbook)1617**Исходный код:** [Lib/logging/\_\_init\_\_.py](https://python-all.ru/src/3.4/Lib/logging/__init__.py)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.4/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.4/library/logging.html#levels).6566Изменено в версии 3.2: Параметр *lvl* теперь принимает строковое представление уровня, например 'INFO', как альтернативу целочисленным константам, таким как `INFO`. Однако учтите, что уровни внутри хранятся как целые числа, и такие методы, как, например, [`getEffectiveLevel()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.getEffectiveLevel) и [`isEnabledFor()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.isEnabledFor), будут возвращать или ожидать на вход целые числа.6768#### `Logger.isEnabledFor(lvl)`6970Указывает, будет ли сообщение с уровнем серьёзности *lvl* обработано этим логгером. Этот метод сначала проверяет уровень, установленный на уровне модуля с помощью `logging.disable(lvl)`, а затем эффективный уровень логгера, определяемый [`getEffectiveLevel()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.getEffectiveLevel).7172#### `Logger.getEffectiveLevel()`7374Возвращает эффективный уровень для этого логгера. Если с помощью [`setLevel()`](https://python-all.ru/3.4/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*, который, если не равен false, приводит к добавлению информации об исключении в сообщение логирования. Если предоставлен кортеж исключения (в формате, возвращаемом [`sys.exc_info()`](https://python-all.ru/3.4/library/sys.html#sys.exc_info)), он используется; в противном случае вызывается [`sys.exc_info()`](https://python-all.ru/3.4/library/sys.html#sys.exc_info) для получения информации об исключении.8788Второй необязательный именованный аргумент – *stack\_info*, по умолчанию `False`. Если true, в сообщение логирования добавляется информация о стеке, включая сам вызов логирования. Обратите внимание, что это не та же информация о стеке, что отображается при указании *exc\_info*: первая – это кадры стека от низа стека до вызова логирования в текущем потоке, тогда как вторая – информация о кадрах стека, которые были развёрнуты после исключения в процессе поиска обработчиков исключений.8990Можно указать *stack\_info* независимо от *exc\_info*, например, чтобы просто показать, как был достигнут определённый участок кода, даже если исключения не возникали. Кадры стека выводятся после строки заголовка, которая гласит:9192```python93Stack (most recent call last):94```9596This mimics the `Traceback (most recent call last):` which is used when displaying exception frames.9798Третий именованный аргумент – *extra*, который можно использовать для передачи словаря, который заполняет \_\_dict\_\_ объекта LogRecord, созданного для события журналирования, пользовательскими атрибутами. Затем эти пользовательские атрибуты можно использовать по своему усмотрению. Например, их можно включать в журналируемые сообщения. Например:99100```python101FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'102logging.basicConfig(format=FORMAT)103d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}104logger = logging.getLogger('tcpserver')105logger.warning('Protocol problem: %s', 'connection reset', extra=d)106```107108выведет что-то вроде109110```python1112006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset112```113114Ключи в словаре, передаваемом в *extra*, не должны совпадать с ключами, используемыми системой логирования. (См. документацию [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) для получения дополнительной информации о том, какие ключи использует система логирования.)115116Если вы решили использовать эти атрибуты в регистрируемых сообщениях, нужно соблюдать осторожность. Например, в приведённом выше примере [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) был настроен со строкой форматирования, которая ожидает атрибуты 'clientip' и 'user' в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет записано из-за возникновения исключения форматирования строки. Поэтому в данном случае всегда нужно передавать словарь *extra* с этими ключами.117118Хотя это может раздражать, данная возможность предназначена для использования в специализированных ситуациях, таких как многопоточные серверы, где один и тот же код выполняется в разных контекстах, и интересующие условия зависят от этого контекста (например, IP-адрес удалённого клиента и имя аутентифицированного пользователя, как в приведённом выше примере). В таких ситуациях, скорее всего, будут использоваться специализированные [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter)ы с определёнными `Handler`ами.119120Новое в версии 3.2: Был добавлен параметр *stack\_info*.121122#### `Logger.info(msg, *args, **kwargs)`123124Записывает сообщение уровня `INFO` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).125126#### `Logger.warning(msg, *args, **kwargs)`127128Записывает сообщение уровня `WARNING` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).129130> **Примечание**131>132> Существует устаревший метод `warn`, который функционально идентичен `warning`. Поскольку `warn` устарел, не используйте его – вместо него используйте `warning`.133134#### `Logger.error(msg, *args, **kwargs)`135136Записывает сообщение уровня `ERROR` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).137138#### `Logger.critical(msg, *args, **kwargs)`139140Записывает сообщение с уровнем `CRITICAL` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).141142#### `Logger.log(lvl, msg, *args, **kwargs)`143144Записывает сообщение с целочисленным уровнем *lvl* в этот логгер. Остальные аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).145146#### `Logger.exception(msg, *args, **kwargs)`147148Записывает сообщение с уровнем `ERROR` в этот логгер. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug). Информация об исключении добавляется в сообщение лога. Этот метод следует вызывать только из обработчика исключений.149150#### `Logger.addFilter(filt)`151152Добавляет указанный фильтр *filt* к этому логгеру.153154#### `Logger.removeFilter(filt)`155156Удаляет указанный фильтр *filt* из этого логгера.157158#### `Logger.filter(record)`159160Применяет фильтры этого логгера к записи и возвращает истинное значение, если запись должна быть обработана. Фильтры опрашиваются по очереди, пока один из них не вернет ложное значение. Если ни один из них не вернет ложное значение, запись будет обработана (передана обработчикам). Если какой-либо фильтр возвращает ложное значение, дальнейшая обработка записи не выполняется.161162#### `Logger.addHandler(hdlr)`163164Добавляет указанный обработчик *hdlr* к этому логгеру.165166#### `Logger.removeHandler(hdlr)`167168Удаляет указанный обработчик *hdlr* из этого логгера.169170#### `Logger.findCaller(stack_info=False)`171172Находит имя исходного файла и номер строки вызывающего кода. Возвращает имя файла, номер строки, имя функции и информацию о стеке в виде кортежа из 4 элементов. Информация о стеке возвращается как *None*, если *stack\_info* не равно *True*.173174#### `Logger.handle(record)`175176Обрабатывает запись, передавая её всем обработчикам, связанным с этим логгером и его предками (пока не будет найдено ложное значение *propagate*). Этот метод используется для распакованных записей, полученных из сокета, а также для записей, созданных локально. Фильтрация на уровне логгера применяется с помощью [`filter()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.filter).177178#### `Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)`179180Это фабричный метод, который можно переопределить в подклассах для создания специализированных экземпляров [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord).181182#### `Logger.hasHandlers()`183184Проверяет, есть ли у этого логгера настроенные обработчики. Для этого выполняется поиск обработчиков в этом логгере и его родителях в иерархии логгеров. Возвращает `True`, если обработчик найден, иначе `False`. Метод прекращает поиск вверх по иерархии, как только будет найден логгер, у которого атрибут 'propagate' установлен в False – это будет последний логгер, проверяемый на наличие обработчиков.185186Новое в версии 3.2.187188## 16.6.2. Уровни логирования189190Числовые значения уровней журналирования приведены в следующей таблице. Они представляют интерес в первую очередь, если вы хотите определить собственные уровни и хотите, чтобы они имели определенные значения относительно предопределенных уровней. Если вы определяете уровень с тем же числовым значением, он перезаписывает предопределенное значение; предопределенное имя теряется.191192| Уровень | Числовое значение |193| --- | --- |194| `CRITICAL` | 50 |195| `ERROR` | 40 |196| `WARNING` | 30 |197| `INFO` | 20 |198| `DEBUG` | 10 |199| `NOTSET` | 0 |200201## 16.6.3. Объекты Handler202203Обработчики имеют следующие атрибуты и методы. Обратите внимание, что `Handler` никогда не создаётся напрямую; этот класс служит базой для более полезных подклассов. Однако метод [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) в подклассах должен вызывать [`Handler.__init__()`](https://python-all.ru/3.4/library/logging.html#logging.Handler.__init__).204205#### `Handler.__init__(level=NOTSET)`206207Инициализирует экземпляр `Handler`, устанавливая его уровень, устанавливая список фильтров в пустой список и создавая блокировку (с помощью [`createLock()`](https://python-all.ru/3.4/library/logging.html#logging.Handler.createLock)) для сериализации доступа к механизму ввода-вывода.208209#### `Handler.createLock()`210211Инициализирует блокировку потока, которую можно использовать для сериализации доступа к нижележащей функциональности ввода-вывода, которая может не быть потокобезопасной.212213#### `Handler.acquire()`214215Захватывает блокировку потока, созданную с помощью [`createLock()`](https://python-all.ru/3.4/library/logging.html#logging.Handler.createLock).216217#### `Handler.release()`218219Освобождает блокировку потока, полученную с помощью [`acquire()`](https://python-all.ru/3.4/library/logging.html#logging.Handler.acquire).220221#### `Handler.setLevel(lvl)`222223Устанавливает порог для этого обработчика в *lvl*. Сообщения журнала, которые менее серьезны, чем *lvl*, будут игнорироваться. При создании обработчика уровень устанавливается в `NOTSET` (из-за чего обрабатываются все сообщения).224225Список уровней см. в [*Уровни логирования*](https://python-all.ru/3.4/library/logging.html#levels).226227Изменено в версии 3.2: Параметр *lvl* теперь принимает строковое представление уровня, например 'INFO', в качестве альтернативы целочисленным константам, таким как `INFO`.228229#### `Handler.setFormatter(form)`230231Устанавливает [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) для этого обработчика в *form*.232233#### `Handler.addFilter(filt)`234235Добавляет указанный фильтр *фильтр* в данный обработчик.236237#### `Handler.removeFilter(filt)`238239Удаляет указанный фильтр *фильтр* из данного обработчика.240241#### `Handler.filter(record)`242243Применяет фильтры этого обработчика к записи и возвращает истинное значение, если запись должна быть обработана. Фильтры опрашиваются по очереди, пока один из них не вернет ложное значение. Если ни один из них не вернет ложное значение, запись будет отправлена. Если какой-либо фильтр возвращает ложное значение, обработчик не будет отправлять запись.244245#### `Handler.flush()`246247Обеспечивает сброс всего вывода логирования. Данная версия ничего не делает и предназначена для реализации в подклассах.248249#### `Handler.close()`250251Освобождает все ресурсы, используемые обработчиком. Эта версия не производит вывод, но удаляет обработчик из внутреннего списка обработчиков, который закрывается при вызове [`shutdown()`](https://python-all.ru/3.4/library/logging.html#logging.shutdown). Подклассы должны гарантировать, что этот метод вызывается из переопределенных методов [`close()`](https://python-all.ru/3.4/library/logging.html#logging.Handler.close).252253#### `Handler.handle(record)`254255Условно выдает указанную запись логирования в зависимости от фильтров, которые могут быть добавлены к обработчику. Оборачивает фактическую выдачу записи в захват/освобождение блокировки потока ввода-вывода.256257#### `Handler.handleError(record)`258259Этот метод должен вызываться из обработчиков при возникновении исключения во время вызова [`emit()`](https://python-all.ru/3.4/library/logging.html#logging.Handler.emit). Если атрибут уровня модуля `raiseExceptions` равен `False`, исключения молча игнорируются. Обычно это то, что нужно для системы журналирования – большинство пользователей не будут беспокоиться об ошибках в системе журналирования, они больше заинтересованы в ошибках приложения. Однако вы можете заменить это на собственный обработчик, если захотите. Указанная запись (record) – это та, которая обрабатывалась, когда произошло исключение. (Значение по умолчанию `raiseExceptions` равно `True`, так как это более полезно во время разработки).260261#### `Handler.format(record)`262263Форматирует запись – если задан форматировщик, использует его. В противном случае использует форматировщик по умолчанию для модуля.264265#### `Handler.emit(record)`266267Делает все необходимое для фактической записи указанной записи журнала. Эта версия предназначена для реализации в подклассах и поэтому вызывает [`NotImplementedError`](https://python-all.ru/3.4/library/exceptions.html#NotImplementedError).268269Список стандартных обработчиков см. в [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers).270271## 16.6.4. Объекты Formatter272273Объекты [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) имеют следующие атрибуты и методы. Они отвечают за преобразование [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) в (обычно) строку, которая может быть интерпретирована человеком или внешней системой. Базовый [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) позволяет указать строку форматирования. Если она не указана, используется значение по умолчанию `'%(message)s'`, которое включает только сообщение из вызова журналирования. Чтобы добавить дополнительную информацию в форматированный вывод (например, временную метку), читайте дальше.274275Formatter можно инициализировать строкой форматирования, которая использует знание атрибутов [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) – например, упомянутое выше значение по умолчанию использует тот факт, что сообщение и аргументы пользователя предварительно форматируются в атрибут *message* объекта [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord). Эта строка форматирования содержит стандартные ключи отображения в стиле % языка Python. Дополнительную информацию о форматировании строк см. в разделе [*printf-style String Formatting*](https://python-all.ru/3.4/library/stdtypes.html#old-string-formatting).276277Полезные ключи отображения в [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) приведены в разделе [*LogRecord attributes*](https://python-all.ru/3.4/library/logging.html#logrecord-attributes).278279#### `class logging.Formatter(fmt=None, datefmt=None, style='%')`280281Возвращает новый экземпляр класса [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter). Экземпляр инициализируется строкой форматирования для всего сообщения, а также строкой форматирования для части даты/времени сообщения. Если *fmt* не указан, используется `'%(message)s'`. Если *datefmt* не указан, используется формат даты ISO8601.282283Параметр *style* может быть одним из ‘%’, ‘{‘ или ‘$’ и определяет, как строка форматирования будет объединяться с данными: с помощью %-форматирования, [`str.format()`](https://python-all.ru/3.4/library/stdtypes.html#str.format) или [`string.Template`](https://python-all.ru/3.4/library/string.html#string.Template). См. [*Using particular formatting styles throughout your application*](https://python-all.ru/3.4/howto/logging-cookbook.html#formatting-styles) для получения дополнительной информации об использовании форматирования в стиле { и $ для сообщений журнала.284285Изменено в версии 3.2: Добавлен параметр *style*.286287#### `format(record)`288289Словарь атрибутов записи используется как операнд для операции форматирования строки. Возвращает результирующую строку. Перед форматированием словаря выполняется несколько подготовительных шагов. Атрибут *message* записи вычисляется с помощью *msg* % *args*. Если строка форматирования содержит `'(asctime)'`, вызывается [`formatTime()`](https://python-all.ru/3.4/library/logging.html#logging.Formatter.formatTime) для форматирования времени события. Если присутствует информация об исключении, она форматируется с помощью [`formatException()`](https://python-all.ru/3.4/library/logging.html#logging.Formatter.formatException) и добавляется к сообщению. Обратите внимание, что отформатированная информация об исключении кэшируется в атрибуте *exc\_text*. Это полезно, поскольку информацию об исключении можно сериализовать и отправить по сети, но следует быть осторожным, если имеется более одного подкласса [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter), который настраивает форматирование информации об исключении. В этом случае вам придется очищать кэшированное значение после того, как форматировщик выполнит свое форматирование, чтобы следующий форматировщик, обрабатывающий событие, не использовал кэшированное значение, а пересчитал его заново.290291Если информация о стеке доступна, она добавляется после информации об исключении, с использованием [`formatStack()`](https://python-all.ru/3.4/library/logging.html#logging.Formatter.formatStack) для преобразования при необходимости.292293#### `formatTime(record, datefmt=None)`294295Этот метод должен вызываться из [`format()`](https://python-all.ru/3.4/library/functions.html#format) форматировщиком, который хочет использовать отформатированное время. Этот метод может быть переопределен в форматировщиках для любых специфических требований, но базовое поведение следующее: если указан *datefmt* (строка), он используется с [`time.strftime()`](https://python-all.ru/3.4/library/time.html#time.strftime) для форматирования времени создания записи. В противном случае используется формат ISO8601. Возвращается результирующая строка.296297Эта функция использует настраиваемую пользователем функцию для преобразования времени создания в кортеж. По умолчанию используется [`time.localtime()`](https://python-all.ru/3.4/library/time.html#time.localtime); чтобы изменить это для конкретного экземпляра форматировщика, установите атрибут `converter` на функцию с той же сигнатурой, что и [`time.localtime()`](https://python-all.ru/3.4/library/time.html#time.localtime) или [`time.gmtime()`](https://python-all.ru/3.4/library/time.html#time.gmtime). Чтобы изменить его для всех форматировщиков, например, если вы хотите, чтобы все временные метки отображались в GMT, установите атрибут `converter` в классе `Formatter`.298299Изменено в версии 3.3: Ранее формат ISO 8601 по умолчанию был жестко закодирован, как в этом примере: `2010-09-06 22:38:15,292`, где часть до запятой обрабатывается строкой форматирования strptime (`'%Y-%m-%d %H:%M:%S'`), а часть после запятой – это значение миллисекунд. Поскольку strptime не имеет заполнителя для миллисекунд, значение миллисекунд добавляется с помощью другой строки форматирования, `'%s,%03d'` – и обе эти строки форматирования были жестко закодированы в этом методе. С этим изменением эти строки определяются как атрибуты уровня класса, которые при желании можно переопределить на уровне экземпляра. Имена атрибутов: `default_time_format` (для строки форматирования strptime) и `default_msec_format` (для добавления значения миллисекунд).300301#### `formatException(exc_info)`302303Форматирует указанную информацию об исключении (стандартный кортеж исключения, возвращаемый [`sys.exc_info()`](https://python-all.ru/3.4/library/sys.html#sys.exc_info)) в виде строки. Эта реализация по умолчанию просто использует [`traceback.print_exception()`](https://python-all.ru/3.4/library/traceback.html#traceback.print_exception). Полученная строка возвращается.304305#### `formatStack(stack_info)`306307Форматирует указанную информацию о стеке (строку, возвращаемую [`traceback.print_stack()`](https://python-all.ru/3.4/library/traceback.html#traceback.print_stack), но с удалённым последним символом новой строки) в виде строки. Эта реализация по умолчанию просто возвращает входное значение.308309## 16.6.5. Объекты Filter310311`Фильтры` могут использоваться `обработчиками` и `логгерами` для более сложной фильтрации, чем та, что обеспечивается уровнями. Базовый класс фильтра пропускает только события, которые находятся ниже определённой точки в иерархии логгеров. Например, фильтр, инициализированный строкой 'A.B', будет пропускать события, зарегистрированные логгерами 'A.B', 'A.B.C', 'A.B.C.D', 'A.B.D' и т.д., но не 'A.BB', 'B.A.B' и т.д. Если инициализировать пустой строкой, пропускаются все события.312313#### `class logging.Filter(name='')`314315Возвращает экземпляр класса [`Filter`](https://python-all.ru/3.4/library/logging.html#logging.Filter). Если указан *name*, он задаёт имя логгера, который вместе со своими дочерними элементами будет пропускать события через фильтр. Если *name* – пустая строка, пропускаются все события.316317#### `filter(record)`318319Следует ли регистрировать указанную запись? Возвращает ноль, если нет, и ненулевое значение, если да. Если это уместно, запись может быть изменена на месте данным методом.320321Обратите внимание, что фильтры, прикреплённые к обработчикам, проверяются до того, как событие будет отправлено обработчиком, тогда как фильтры, прикреплённые к логгерам, проверяются при каждом логировании события (с помощью [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug), [`info()`](https://python-all.ru/3.4/library/logging.html#logging.info) и т.д.) перед отправкой события обработчикам. Это означает, что события, созданные дочерними логгерами, не будут фильтроваться настройкой фильтра логгера, если только фильтр не был также применён к этим дочерним логгерам.322323На самом деле не обязательно создавать подкласс `Filter`: можно передать любой экземпляр, у которого есть метод `filter` с той же семантикой.324325Изменено в версии 3.2: Больше не нужно создавать специализированные классы `Filter` или использовать другие классы с методом `filter`: можно использовать функцию (или другой вызываемый объект) в качестве фильтра. Логика фильтрации проверяет, есть ли у объекта фильтра атрибут `filter`: если есть, предполагается, что это `Filter`, и вызывается его метод [`filter()`](https://python-all.ru/3.4/library/logging.html#logging.Filter.filter). В противном случае предполагается, что это вызываемый объект, и он вызывается с записью в качестве единственного параметра. Возвращаемое значение должно соответствовать тому, что возвращает [`filter()`](https://python-all.ru/3.4/library/logging.html#logging.Filter.filter).326327Хотя фильтры в первую очередь используются для фильтрации записей на основе более сложных критериев, чем уровни, они видят каждую запись, которая обрабатывается обработчиком или регистратором, к которому они прикреплены: это может быть полезно, если нужно, например, подсчитать, сколько записей было обработано конкретным регистратором или обработчиком, или добавить, изменить или удалить атрибуты в обрабатываемом LogRecord. Очевидно, что изменение LogRecord требует определённой осторожности, но это позволяет внедрять контекстную информацию в журналы (см. [*Использование фильтров для передачи контекстной информации*](https://python-all.ru/3.4/howto/logging-cookbook.html#filters-contextual)).328329## 16.6.6. Объекты LogRecord330331Экземпляры [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) создаются автоматически [`Logger`](https://python-all.ru/3.4/library/logging.html#logging.Logger) каждый раз при логировании чего-либо, и могут быть созданы вручную с помощью [`makeLogRecord()`](https://python-all.ru/3.4/library/logging.html#logging.makeLogRecord) (например, из сериализованного события, полученного по сети).332333#### `class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)`334335Содержит всю информацию, относящуюся к регистрируемому событию.336337Основная информация передаётся в `msg` и `args`, которые объединяются с помощью `msg % args` для создания поля `message` записи.338339| Параметры: | **name** – Имя логгера, используемого для регистрации события, представленного этой LogRecord. Обратите внимание, что это имя всегда будет иметь данное значение, даже если событие может быть отправлено обработчиком, прикреплённым к другому (родительскому) логгеру. **level** – числовой уровень события логирования (один из DEBUG, INFO и т.д.). Обратите внимание, что это преобразуется в *два* атрибута LogRecord: `levelno` для числового значения и `levelname` для соответствующего имени уровня. **pathname** – Полный путь к исходному файлу, в котором был выполнен вызов логирования. **lineno** – Номер строки в исходном файле, в которой был выполнен вызов логирования. **msg** – Описание события, возможно, строка форматирования с заполнителями для переменных данных. **args** – Переменные данные для подстановки в аргумент *msg* для получения описания события. **exc\_info** – кортеж исключения с текущей информацией об исключении, или *None*, если информация об исключении отсутствует. **func** – Имя функции или метода, из которого был выполнен вызов логирования. **sinfo** – Текстовая строка, представляющая информацию о стеке от основания стека в текущем потоке до вызова логирования. |340| --- | --- |341342#### `getMessage()`343344Возвращает сообщение для данного экземпляра [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) после объединения любых предоставленных пользователем аргументов с сообщением. Если предоставленный пользователем аргумент сообщения при вызове логирования не является строкой, для его преобразования в строку вызывается [`str()`](https://python-all.ru/3.4/library/stdtypes.html#str). Это позволяет использовать пользовательские классы в качестве сообщений, чей метод `__str__` может возвращать фактическую строку форматирования для использования.345346Изменено в версии 3.2: Создание `LogRecord` стало более настраиваемым благодаря предоставлению фабрики, которая используется для создания записи. Фабрику можно задать с помощью [`getLogRecordFactory()`](https://python-all.ru/3.4/library/logging.html#logging.getLogRecordFactory) и [`setLogRecordFactory()`](https://python-all.ru/3.4/library/logging.html#logging.setLogRecordFactory) (см. это для сигнатуры фабрики).347348Эту функциональность можно использовать для внедрения собственных значений в LogRecord при его создании. Можно воспользоваться следующим шаблоном:349350```python351old_factory = logging.getLogRecordFactory()352353def record_factory(*args, **kwargs):354 record = old_factory(*args, **kwargs)355 record.custom_attribute = 0xdecafbad356 return record357358logging.setLogRecordFactory(record_factory)359```360361При таком шаблоне можно объединять несколько фабрик, и пока они не перезаписывают атрибуты друг друга или случайно не перезаписывают стандартные атрибуты, перечисленные выше, сюрпризов быть не должно.362363## 16.6.7. Атрибуты LogRecord364365LogRecord имеет ряд атрибутов, большинство из которых получены из параметров конструктора. (Обратите внимание, что имена не всегда точно соответствуют между параметрами конструктора LogRecord и атрибутами LogRecord.) Эти атрибуты можно использовать для объединения данных из записи в строку форматирования. В следующей таблице перечислены (в алфавитном порядке) имена атрибутов, их значения и соответствующий заполнитель в строке форматирования в стиле %.366367Если используется форматирование через {} ([`str.format()`](https://python-all.ru/3.4/library/stdtypes.html#str.format)), можно использовать `{attrname}` в качестве заполнителя в строке форматирования. Если используется $-форматирование ([`string.Template`](https://python-all.ru/3.4/library/string.html#string.Template)), используйте форму `${attrname}`. В обоих случаях, конечно, замените `attrname` на фактическое имя атрибута, которое требуется использовать.368369В случае форматирования через {} можно указать флаги форматирования, разместив их после имени атрибута, отделив двоеточием. Например: заполнитель `{msecs:03d}` отформатирует значение миллисекунд `4` как `004`. Обратитесь к документации [`str.format()`](https://python-all.ru/3.4/library/stdtypes.html#str.format) для получения полной информации о доступных опциях.370371| Имя атрибута | Формат | Описание |372| --- | --- | --- |373| аргументы | Форматировать это самостоятельно не требуется. | Кортеж аргументов, объединяемых с `msg` для создания `message`, или словарь, значения которого используются для объединения (когда есть только один аргумент, и это словарь). |374| asctime | `%(asctime)s` | Время создания [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) в удобочитаемом формате. По умолчанию оно имеет вид '2003-07-08 16:49:45,896' (числа после запятой – миллисекундная часть времени). |375| created | `%(created)f` | Время создания [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) (возвращаемое [`time.time()`](https://python-all.ru/3.4/library/time.html#time.time)). |376| exc\_info | Форматировать это самостоятельно не требуется. | Кортеж исключения (как в `sys.exc_info`) или *None*, если исключения не произошло. |377| filename | `%(filename)s` | Имя файла из `пути`. |378| funcName | `%(funcName)s` | Имя функции, содержащей вызов логирования. |379| levelname | `%(levelname)s` | Текстовый уровень логирования сообщения (`'DEBUG'`, `'INFO'`, `'WARNING'`, `'ERROR'`, `'CRITICAL'`). |380| levelno | `%(levelno)s` | Числовой уровень логирования сообщения (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`). |381| lineno | `%(lineno)d` | Номер строки исходного кода, из которой был сделан вызов логирования (если доступен). |382| модуль | `%(module)s` | Модуль (часть имени из `filename`). |383| msecs | `%(msecs)d` | Миллисекундная часть времени, когда был создан [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord). |384| message | `%(message)s` | Записанное сообщение, вычисляемое как `msg % args`. Устанавливается при вызове [`Formatter.format()`](https://python-all.ru/3.4/library/logging.html#logging.Formatter.format). |385| msg | Форматировать это самостоятельно не требуется. | Строка форматирования, переданная в исходном вызове логирования. Объединяется с `args` для получения `message` или произвольного объекта (см. [*Использование произвольных объектов в качестве сообщений*](https://python-all.ru/3.4/howto/logging.html#arbitrary-object-messages)). |386| имя | `%(name)s` | Имя регистратора, использованного для записи вызова. |387| pathname | `%(pathname)s` | Полный путь к исходному файлу, из которого был сделан вызов логирования (если доступен). |388| процесс | `%(process)d` | Идентификатор процесса (если доступен). |389| processName | `%(processName)s` | Имя процесса (если доступно). |390| relativeCreated | `%(relativeCreated)d` | Время в миллисекундах, когда LogRecord был создан, относительно времени загрузки модуля logging. |391| stack\_info | Форматировать это самостоятельно не требуется. | Информация о стековых фреймах (где доступна) от дна стека в текущем потоке до стекового фрейма включительно, соответствующего вызову логирования, который привёл к созданию этой записи. |392| поток | `%(thread)d` | Идентификатор потока (если доступен). |393| threadName | `%(threadName)s` | Имя потока (если доступно). |394395Изменено в версии 3.1: *processName* был добавлен.396397## 16.6.8. Объекты LoggerAdapter398399Экземпляры [`LoggerAdapter`](https://python-all.ru/3.4/library/logging.html#logging.LoggerAdapter) используются для удобной передачи контекстной информации в вызовы логирования. Пример использования см. в разделе [*добавления контекстной информации в вывод логирования*](https://python-all.ru/3.4/howto/logging-cookbook.html#context-info).400401#### `class logging.LoggerAdapter(logger, extra)`402403Возвращает экземпляр [`LoggerAdapter`](https://python-all.ru/3.4/library/logging.html#logging.LoggerAdapter), инициализированный базовым экземпляром [`Logger`](https://python-all.ru/3.4/library/logging.html#logging.Logger) и объектом, подобным словарю.404405#### `process(msg, kwargs)`406407Изменяет сообщение и/или именованные аргументы, переданные в вызов логирования, чтобы вставить контекстную информацию. Эта реализация берёт объект, переданный как *extra* конструктору, и добавляет его в *kwargs* с ключом 'extra'. Возвращаемое значение – кортеж (*msg*, *kwargs*), содержащий (возможно изменённые) версии переданных аргументов.408409В дополнение к вышеперечисленному, [`LoggerAdapter`](https://python-all.ru/3.4/library/logging.html#logging.LoggerAdapter) поддерживает следующие методы [`Logger`](https://python-all.ru/3.4/library/logging.html#logging.Logger): [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.debug), [`info()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.info), [`warning()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.warning), [`error()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.error), [`exception()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.exception), [`critical()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.critical), [`log()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.log), [`isEnabledFor()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.isEnabledFor), [`getEffectiveLevel()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.getEffectiveLevel), [`setLevel()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.setLevel) и [`hasHandlers()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.hasHandlers). Сигнатуры этих методов совпадают с их аналогами в [`Logger`](https://python-all.ru/3.4/library/logging.html#logging.Logger), поэтому два типа экземпляров можно использовать взаимозаменяемо.410411Изменено в версии 3.2: Методы [`isEnabledFor()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.isEnabledFor), [`getEffectiveLevel()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.getEffectiveLevel), [`setLevel()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.setLevel) и [`hasHandlers()`](https://python-all.ru/3.4/library/logging.html#logging.Logger.hasHandlers) были добавлены в [`LoggerAdapter`](https://python-all.ru/3.4/library/logging.html#logging.LoggerAdapter). Эти методы делегируют выполнение базовому регистратору.412413## 16.6.9. Потокобезопасность414415Модуль logging спроектирован так, чтобы быть потокобезопасным без каких-либо специальных действий требуемых от его клиентов. Это достигается за счёт использования threading блокировок; одна блокировка сериализует доступ к общим данным модуля, а каждый обработчик также создаёт блокировку для сериализации доступа к своему нижележащему вводу-выводу.416417Если вы реализуете асинхронные обработчики сигналов с помощью модуля [`signal`](https://python-all.ru/3.4/library/signal.html#module-signal), вы можете не иметь возможности использовать логирование из таких обработчиков. Это связано с тем, что реализации блокировок в модуле [`threading`](https://python-all.ru/3.4/library/threading.html#module-threading) не всегда реентерабельны, и поэтому их нельзя вызывать из таких обработчиков сигналов.418419## 16.6.10. Функции уровня модуля420421В дополнение к классам, описанным выше, существует ряд функций уровня модуля.422423#### `logging.getLogger(name=None)`424425Возвращает регистратор с указанным именем или, если имя равно `None`, возвращает корневой регистратор иерархии. Если имя указано, оно обычно представляет собой иерархическое имя с точками в качестве разделителей, например *'a'*, *'a.b'* или *'a.b.c.d'*. Выбор этих имен полностью зависит от разработчика, использующего логирование.426427Все вызовы этой функции с одним и тем же именем возвращают один и тот же экземпляр логгера. Это означает, что экземпляры логгера никогда не нужно передавать между различными частями приложения.428429#### `logging.getLoggerClass()`430431Возвращает либо стандартный класс [`Logger`](https://python-all.ru/3.4/library/logging.html#logging.Logger), либо последний класс, переданный в [`setLoggerClass()`](https://python-all.ru/3.4/library/logging.html#logging.setLoggerClass). Эта функция может быть вызвана из определения нового класса, чтобы гарантировать, что установка настраиваемого класса [`Logger`](https://python-all.ru/3.4/library/logging.html#logging.Logger) не отменит настройки, уже применённые другим кодом. Например:432433```python434class MyLogger(logging.getLoggerClass()):435 # ... переопределить поведение здесь436```437438#### `logging.getLogRecordFactory()`439440Возвращает вызываемый объект, который используется для создания [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord).441442Новое в версии 3.2: Эта функция была предоставлена вместе с [`setLogRecordFactory()`](https://python-all.ru/3.4/library/logging.html#logging.setLogRecordFactory), чтобы дать разработчикам больше контроля над тем, как конструируется [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord), представляющий событие логирования.443444См. [`setLogRecordFactory()`](https://python-all.ru/3.4/library/logging.html#logging.setLogRecordFactory) для получения дополнительной информации о том, как вызывается фабрика.445446#### `logging.debug(msg, *args, **kwargs)`447448Записывает сообщение с уровнем `DEBUG` в корневой регистратор. *msg* – это форматная строка сообщения, а *args* – аргументы, которые объединяются с *msg* с помощью оператора форматирования строк. (Обратите внимание, что это означает, что в форматной строке можно использовать ключевые слова вместе с единственным аргументом-словарём.)449450В *kwargs* проверяются три именованных аргумента: *exc\_info*, который, если его значение не равно false, приводит к добавлению информации об исключении в сообщение логирования. Если предоставлен кортеж исключения (в формате, возвращаемом [`sys.exc_info()`](https://python-all.ru/3.4/library/sys.html#sys.exc_info)), используется он; в противном случае вызывается [`sys.exc_info()`](https://python-all.ru/3.4/library/sys.html#sys.exc_info) для получения информации об исключении.451452Второй необязательный именованный аргумент – *stack\_info*, по умолчанию `False`. Если равен True, в сообщение логирования добавляется информация о стеке, включая сам вызов логирования. Обратите внимание, что это не та же информация о стеке, что отображается при указании *exc\_info*: первое – это кадры стека от низа стека до вызова логирования в текущем потоке, тогда как второе – информация о кадрах стека, которые были размотаны после исключения при поиске обработчиков исключений.453454Можно указать *stack\_info* независимо от *exc\_info*, например, чтобы просто показать, как был достигнут определённый участок кода, даже если исключения не возникали. Кадры стека выводятся после строки заголовка, которая гласит:455456```python457Stack (most recent call last):458```459460Это имитирует `Traceback (most recent call last):`, который используется при отображении кадров исключений.461462Третий необязательный именованный аргумент – *extra*, с помощью которого можно передать словарь, используемый для заполнения \_\_dict\_\_ объекта LogRecord, созданного для события логирования, пользовательскими атрибутами. Затем эти пользовательские атрибуты можно использовать по своему усмотрению. Например, их можно включать в логируемые сообщения. Пример:463464```python465FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'466logging.basicConfig(format=FORMAT)467d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}468logging.warning('Protocol problem: %s', 'connection reset', extra=d)469```470471выведет что-то вроде:472473```python4742006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset475```476477Ключи в словаре, переданном в *extra*, не должны пересекаться с ключами, используемыми системой логирования. (См. документацию [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) для получения дополнительной информации о том, какие ключи используются системой логирования.)478479Если вы решите использовать эти атрибуты в логируемых сообщениях, нужно соблюдать осторожность. Например, в приведённом выше примере [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) настроен с форматной строкой, которая ожидает 'clientip' и 'user' в словаре атрибутов LogRecord. Если они отсутствуют, сообщение не будет записано, так как возникнет исключение форматирования строки. Поэтому в этом случае всегда нужно передавать словарь *extra* с этими ключами.480481Хотя это может быть раздражающим, эта функция предназначена для использования в специализированных обстоятельствах, таких как многопоточные серверы, где один и тот же код выполняется во многих контекстах, и интересующие условия зависят от этого контекста (например, IP-адрес удалённого клиента и имя аутентифицированного пользователя в приведённом выше примере). В таких обстоятельствах, скорее всего, будут использоваться специализированные [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) с конкретными `Handler`.482483Новое в версии 3.2: Был добавлен параметр *stack\_info*.484485#### `logging.info(msg, *args, **kwargs)`486487Записывает сообщение с уровнем `INFO` в корневой регистратор. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).488489#### `logging.warning(msg, *args, **kwargs)`490491Записывает сообщение с уровнем `WARNING` в корневой регистратор. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).492493> **Примечание**494>495> Существует устаревшая функция `warn`, которая функционально идентична `warning`. Поскольку `warn` устарела, пожалуйста, не используйте её – вместо неё используйте `warning`.496497#### `logging.error(msg, *args, **kwargs)`498499Записывает сообщение с уровнем `ERROR` в корневой регистратор. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).500501#### `logging.critical(msg, *args, **kwargs)`502503Регистрирует сообщение с уровнем `CRITICAL` в корневом логгере. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).504505#### `logging.exception(msg, *args, **kwargs)`506507Регистрирует сообщение с уровнем `ERROR` в корневом логгере. Аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug). Информация об исключении добавляется в сообщение журнала. Эта функция должна вызываться только из обработчика исключений.508509#### `logging.log(level, msg, *args, **kwargs)`510511Регистрирует сообщение с уровнем *level* в корневом логгере. Остальные аргументы интерпретируются так же, как для [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug).512513> **Примечание**514>515> Вышеупомянутые удобные функции уровня модуля, которые делегируют работу корневому логгеру, вызывают [`basicConfig()`](https://python-all.ru/3.4/library/logging.html#logging.basicConfig), чтобы гарантировать доступность хотя бы одного обработчика. Из-за этого их *не* следует использовать в потоках в версиях Python раньше 2.7.1 и 3.2, если только хотя бы один обработчик не был добавлен в корневой логгер *до* запуска потоков. В более ранних версиях Python из-за недостатка потокобезопасности в [`basicConfig()`](https://python-all.ru/3.4/library/logging.html#logging.basicConfig) это может (в редких случаях) привести к многократному добавлению обработчиков в корневой логгер, что, в свою очередь, может привести к появлению нескольких сообщений для одного и того же события.516517#### `logging.disable(lvl)`518519Предоставляет переопределяющий уровень *lvl* для всех логгеров, который имеет приоритет над собственным уровнем логгера. Когда возникает необходимость временно снизить интенсивность вывода журнала во всем приложении, эта функция может быть полезна. Её эффект заключается в отключении всех вызовов журналирования с серьёзностью *lvl* и ниже, так что если вызвать её со значением INFO, то все события INFO и DEBUG будут отброшены, а те, что имеют серьёзность WARNING и выше, будут обрабатываться в соответствии с эффективным уровнем логгера. Если вызвать `logging.disable(logging.NOTSET)`, это фактически удаляет переопределяющий уровень, и вывод журнала снова зависит от эффективных уровней отдельных логгеров.520521#### `logging.addLevelName(lvl, levelName)`522523Связывает уровень *lvl* с текстом *levelName* во внутреннем словаре, который используется для сопоставления числовых уровней с текстовым представлением, например, когда [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) форматирует сообщение. Эта функция также может использоваться для определения собственных уровней. Единственные ограничения: все используемые уровни должны быть зарегистрированы с помощью этой функции, уровни должны быть положительными целыми числами и должны возрастать в порядке увеличения серьёзности.524525> **Примечание**526>527> Если вы планируете определять собственные уровни, обратитесь к разделу [*Пользовательские уровни*](https://python-all.ru/3.4/howto/logging.html#custom-levels).528529#### `logging.getLevelName(lvl)`530531Возвращает текстовое представление уровня журналирования *lvl*. Если уровень является одним из предопределённых уровней `CRITICAL`, `ERROR`, `WARNING`, `INFO` или `DEBUG`, то возвращается соответствующая строка. Если вы связали уровни с именами с помощью [`addLevelName()`](https://python-all.ru/3.4/library/logging.html#logging.addLevelName), то возвращается имя, которое вы связали с *lvl*. Если передано числовое значение, соответствующее одному из определённых уровней, возвращается соответствующее строковое представление. В противном случае возвращается строка 'Level %s' % lvl.532533> **Примечание**534>535> Уровни внутри являются целыми числами (поскольку их нужно сравнивать в логике журналирования). Эта функция используется для преобразования между целочисленным уровнем и именем уровня, отображаемым в форматированном выводе журнала, с помощью спецификатора формата `%(levelname)s` (см. [*атрибуты LogRecord*](https://python-all.ru/3.4/library/logging.html#logrecord-attributes)).536537Изменено в версии 3.4: В версиях Python до 3.4 этой функции также можно было передать текстовый уровень, и она возвращала соответствующее числовое значение уровня. Это недокументированное поведение считалось ошибкой и было удалено в Python 3.4, но восстановлено в 3.4.2 для сохранения обратной совместимости.538539#### `logging.makeLogRecord(attrdict)`540541Создаёт и возвращает новый экземпляр [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord), атрибуты которого определяются *attrdict*. Эта функция полезна для приёма сериализованного (pickled) [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) словаря атрибутов, отправленного через сокет, и восстановления его как экземпляра [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord) на принимающей стороне.542543#### `logging.basicConfig(**kwargs)`544545Выполняет базовую настройку системы журналирования, создавая [`StreamHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.StreamHandler) с форматтером по умолчанию [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) и добавляя его в корневой логгер. Функции [`debug()`](https://python-all.ru/3.4/library/logging.html#logging.debug), [`info()`](https://python-all.ru/3.4/library/logging.html#logging.info), [`warning()`](https://python-all.ru/3.4/library/logging.html#logging.warning), [`error()`](https://python-all.ru/3.4/library/logging.html#logging.error) и [`critical()`](https://python-all.ru/3.4/library/logging.html#logging.critical) будут автоматически вызывать [`basicConfig()`](https://python-all.ru/3.4/library/logging.html#logging.basicConfig), если для корневого логгера не определено ни одного обработчика.546547Эта функция ничего не делает, если для корневого логгера уже настроены обработчики.548549> **Примечание**550>551> Эту функцию следует вызывать из главного потока до запуска других потоков. В версиях Python до 2.7.1 и 3.2, если эта функция вызывается из нескольких потоков, в редких случаях обработчик может быть добавлен в корневой логгер более одного раза, что приводит к неожиданным результатам, например, к дублированию сообщений в логе.552553Поддерживаются следующие аргументы ключевых слов.554555| Формат | Описание |556| --- | --- |557| `filename` | Указывает, что создаётся FileHandler, с использованием указанного имени файла, а не StreamHandler. |558| `filemode` | Задает режим открытия файла, если указан filename (если filemode не указан, по умолчанию используется ‘a’). |559| `format` | Использует указанную строку формата для обработчика. |560| `datefmt` | Использовать указанный формат даты/времени. |561| `style` | Если указан `format`, используйте этот стиль для строки формата. Один из символов: '%', '{' или '$' для %-форматирования, [`str.format()`](https://python-all.ru/3.4/library/stdtypes.html#str.format) или [`string.Template`](https://python-all.ru/3.4/library/string.html#string.Template) соответственно; по умолчанию используется '%', если не указано иное. |562| `level` | Установить уровень корневого регистратора на указанный уровень. |563| `поток данных` | Использует указанный поток для инициализации StreamHandler. Обратите внимание, что этот аргумент несовместим с 'filename' – если указаны оба, возникает `ValueError`. |564| `handlers` | Если указано, это должна быть итерируемая последовательность уже созданных обработчиков для добавления в корневой логгер. Любые обработчики, у которых ещё не установлен форматтер, получат форматтер по умолчанию, создаваемый в этой функции. Обратите внимание, что этот аргумент несовместим с 'filename' или 'поток данных' – если указаны оба, возникает `ValueError`. |565566Изменено в версии 3.2: Добавлен аргумент `style`.567568Изменено в версии 3.3: Добавлен аргумент `handlers`. Добавлены дополнительные проверки для выявления ситуаций, когда указаны несовместимые аргументы (например, `handlers` вместе с `поток данных` или `filename`, или `поток данных` вместе с `filename`).569570#### `logging.shutdown()`571572Сообщает системе логирования о необходимости выполнить упорядоченное завершение работы, сбрасывая и закрывая все обработчики. Эту функцию следует вызывать при завершении приложения, и после этого вызова не следует использовать систему логирования.573574#### `logging.setLoggerClass(klass)`575576Указывает системе логирования использовать класс *klass* при создании экземпляра логгера. Класс должен определять [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) таким образом, чтобы требовался только аргумент name, а [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) должен вызывать `Logger.__init__()`. Эта функция обычно вызывается до создания любых логгеров приложениями, которым требуется использовать собственное поведение логгера.577578#### `logging.setLogRecordFactory(factory)`579580Устанавливает вызываемый объект, который используется для создания [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord).581582| Параметры: | **factory** – вызываемый объект фабрики, используемый для создания записи журнала. |583| --- | --- |584585Новое в версии 3.2: Эта функция была добавлена вместе с [`getLogRecordFactory()`](https://python-all.ru/3.4/library/logging.html#logging.getLogRecordFactory), чтобы предоставить разработчикам больше контроля над тем, как конструируется [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord), представляющий событие логирования.586587Фабрика имеет следующую сигнатуру:588589`factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)`590591> | имя: | Имя регистратора. |592> | --- | --- |593> | уровень: | Уровень логирования (числовой). |594> | fn: | Полный путь к файлу, в котором был выполнен вызов логирования. |595> | lno: | Номер строки в файле, в котором был выполнен вызов логирования. |596> | сообщение: | Сообщение логирования. |597> | аргументы: | Аргументы для сообщения логирования. |598> | exc\_info: | Кортеж исключения или None. |599> | func: | Имя функции или метода, из которого был сделан вызов логирования. |600> | sinfo: | Трассировка стека, например, предоставляемая функцией [`traceback.print_stack()`](https://python-all.ru/3.4/library/traceback.html#traceback.print_stack), показывающая иерархию вызовов. |601> | kwargs: | Дополнительные именованные аргументы. |602603## 16.6.11. Атрибуты уровня модуля604605#### `logging.lastResort`606607Через этот атрибут доступен «обработчик последней надежды». Это [`StreamHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.StreamHandler), который пишет в `sys.stderr` с уровнем `WARNING` и используется для обработки событий логирования при отсутствии какой-либо конфигурации логирования. В конечном итоге сообщение просто выводится в `sys.stderr`. Это заменяет раннее сообщение об ошибке, которое говорило, что «не удалось найти обработчики для логгера XYZ». Если по какой-то причине требуется прежнее поведение, `lastResort` можно установить в `None`.608609Новое в версии 3.2.610611## 16.6.12. Интеграция с модулем warnings612613Функция [`captureWarnings()`](https://python-all.ru/3.4/library/logging.html#logging.captureWarnings) может использоваться для интеграции [`logging`](https://python-all.ru/3.4/library/logging.html#module-logging) с модулем [`warnings`](https://python-all.ru/3.4/library/warnings.html#module-warnings).614615#### `logging.captureWarnings(capture)`616617Эта функция используется для включения и выключения перехвата предупреждений системой логирования.618619Если *capture* равно `True`, предупреждения, выпущенные модулем [`warnings`](https://python-all.ru/3.4/library/warnings.html#module-warnings), будут перенаправлены в систему логирования. В частности, предупреждение будет отформатировано с помощью [`warnings.formatwarning()`](https://python-all.ru/3.4/library/warnings.html#warnings.formatwarning), и результирующая строка будет записана в логгер с именем `'py.warnings'` с уровнем важности `WARNING`.620621Если *capture* равно `False`, перенаправление предупреждений в систему логирования прекратится, и предупреждения будут перенаправляться на исходные места назначения (т.е. те, которые действовали до вызова `captureWarnings(True)`).622623> **См. также**624>625> **Модуль [`logging.config`](https://python-all.ru/3.4/library/logging.config.html#module-logging.config)**626>627> API конфигурации для модуля logging.628>629> **Модуль [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers)**630>631> Полезные обработчики, входящие в состав модуля logging.632>633> **[**PEP 282**](https://python-all.ru/3.4/library/logging.html) – Система логирования**634>635> Предложение, описывающее эту возможность для включения в стандартную библиотеку Python.636>637> **[Оригинальный пакет логирования Python](https://python-all.ru/3.4/library/logging.html)**638>639> Это исходный код пакета640>641> [`logging`](https://python-all.ru/3.4/library/logging.html#module-logging)642>643> . Версия пакета, доступная на этом сайте, подходит для использования с Python 1.5.2, 2.1.x и 2.2.x, которые не включают пакет644>645> [`logging`](https://python-all.ru/3.4/library/logging.html#module-logging)646>647> в стандартную библиотеку.648