logging.handlers.md
1> **Источник:** https://python-all.ru/3.4/library/logging.handlers.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 16.8. [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers) – Обработчики логирования89Важно1011На этой странице представлена только справочная информация. Учебные руководства см. в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/handlers.py](https://python-all.ru/src/3.4/Lib/logging/handlers.py)1819---2021В пакете предоставлены следующие полезные обработчики. Обратите внимание, что три из них ([`StreamHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.StreamHandler), [`FileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.FileHandler) и [`NullHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.NullHandler)) на самом деле определены в самом модуле [`logging`](https://python-all.ru/3.4/library/logging.html#module-logging), но описаны здесь вместе с остальными обработчиками.2223## 16.8.1. StreamHandler2425Класс [`StreamHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.StreamHandler), расположенный в основном пакете [`logging`](https://python-all.ru/3.4/library/logging.html#module-logging), отправляет вывод логирования в такие потоки, как *sys.stdout*, *sys.stderr* или любой файлоподобный объект (или, точнее, любой объект, поддерживающий методы `write()` и `flush()`).2627#### `class logging.StreamHandler(stream=None)`2829Возвращает новый экземпляр класса [`StreamHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.StreamHandler). Если указан параметр *поток данных*, экземпляр использует его для вывода логирования; в противном случае используется *sys.stderr*.3031#### `emit(record)`3233Если указан форматтер, он форматирует запись. Затем запись записывается в поток с завершающим символом. Если присутствует информация об исключении, она форматируется с помощью [`traceback.print_exception()`](https://python-all.ru/3.4/library/traceback.html#traceback.print_exception) и добавляется в поток.3435#### `flush()`3637Сбрасывает поток, вызывая его метод [`flush()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.StreamHandler.flush). Обратите внимание, что метод `close()` наследуется от `Handler` и поэтому не выполняет вывод, так что иногда может потребоваться явный вызов [`flush()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.StreamHandler.flush).3839Изменено в версии 3.2: Теперь у класса `StreamHandler` есть атрибут `terminator`, значение по умолчанию `'\n'`, который используется как завершитель при записи форматированной записи в поток. Если вы не хотите завершать переводом строки, вы можете установить атрибут `terminator` экземпляра обработчика в пустую строку. В предыдущих версиях завершитель был жёстко задан как `'\n'`.4041## 16.8.2. FileHandler4243Класс [`FileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.FileHandler), расположенный в основном пакете [`logging`](https://python-all.ru/3.4/library/logging.html#module-logging), отправляет вывод логирования в файл на диске. Он наследует функциональность вывода от [`StreamHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.StreamHandler).4445#### `class logging.FileHandler(filename, mode='a', encoding=None, delay=False)`4647Возвращает новый экземпляр класса [`FileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.FileHandler). Указанный файл открывается и используется как поток для логирования. Если *mode* не указан, используется `'a'`. Если *encoding* не равен *None*, файл открывается с указанной кодировкой. Если *delay* равен true, открытие файла откладывается до первого вызова [`emit()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.FileHandler.emit). По умолчанию файл растёт бесконечно.4849#### `close()`5051Закрывает файл.5253#### `emit(record)`5455Выводит запись в файл.5657## 16.8.3. NullHandler5859Новое в версии 3.1.6061Класс [`NullHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.NullHandler), расположенный в основном пакете [`logging`](https://python-all.ru/3.4/library/logging.html#module-logging), не выполняет никакого форматирования или вывода. По сути это обработчик-пустышка, предназначенный для разработчиков библиотек.6263#### `class logging.NullHandler`6465Возвращает новый экземпляр класса [`NullHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.NullHandler).6667#### `emit(record)`6869Этот метод ничего не делает.7071#### `handle(record)`7273Этот метод ничего не делает.7475#### `createLock()`7677Этот метод возвращает `None` для блокировки, поскольку нет базового ввода-вывода, доступ к которому необходимо синхронизировать.7879Смотрите [*Настройка логирования для библиотеки*](https://python-all.ru/3.4/howto/logging.html#library-config) для получения дополнительной информации об использовании [`NullHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.NullHandler).8081## 16.8.4. WatchedFileHandler8283The [`WatchedFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.WatchedFileHandler) class, located in the [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers) module, is a `FileHandler` which watches the file it is logging to. If the file changes, it is closed and reopened using the file name.8485Файл может измениться из-за использования таких программ, как *newsyslog* и *logrotate*, которые выполняют ротацию файлов журнала. Этот обработчик, предназначенный для использования в Unix/Linux, следит, не изменился ли файл с момента последнего вызова emit. (Считается, что файл изменился, если изменились его устройство или inode.) Если файл изменился, старый поток файла закрывается, а файл открывается для получения нового потока.8687Этот обработчик не подходит для использования в Windows, потому что в Windows открытые файлы журналов нельзя перемещать или переименовывать – логирование открывает файлы с эксклюзивными блокировками – поэтому нет необходимости в таком обработчике. Кроме того, *ST\_INO* не поддерживается в Windows; [`stat()`](https://python-all.ru/3.4/library/os.html#os.stat) всегда возвращает ноль для этого значения.8889#### `class logging.handlers.WatchedFileHandler(filename[, mode[, encoding[, delay]]])`9091Возвращает новый экземпляр класса [`WatchedFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.WatchedFileHandler). Указанный файл открывается и используется как поток для логирования. Если *mode* не указан, используется `'a'`. Если *encoding* не равен *None*, файл открывается с указанной кодировкой. Если *delay* равен true, открытие файла откладывается до первого вызова [`emit()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.WatchedFileHandler.emit). По умолчанию файл растёт бесконечно.9293#### `emit(record)`9495Выводит запись в файл, но сначала проверяет, изменился ли файл. Если изменился, существующий поток сбрасывается и закрывается, а файл открывается заново, после чего запись выводится в файл.9697## 16.8.5. BaseRotatingHandler9899Класс [`BaseRotatingHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.BaseRotatingHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), является базовым классом для ротационных файловых обработчиков, [`RotatingFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.RotatingFileHandler) и [`TimedRotatingFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler). Обычно не требуется создавать экземпляры этого класса, однако он содержит атрибуты и методы, которые может понадобиться переопределить.100101#### `class logging.handlers.BaseRotatingHandler(filename, mode, encoding=None, delay=False)`102103Параметры такие же, как у `FileHandler`. Атрибуты:104105#### `namer`106107Если этому атрибуту присвоен вызываемый объект, метод [`rotation_filename()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.BaseRotatingHandler.rotation_filename) делегирует вызов этому объекту. Параметры, передаваемые вызываемому объекту, – это те же параметры, что передаются методу [`rotation_filename()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.BaseRotatingHandler.rotation_filename).108109> **Примечание**110>111> Функция namer вызывается довольно много раз во время ротации, поэтому она должна быть максимально простой и быстрой. Она также должна возвращать одинаковый результат для одного и того же входного значения, иначе поведение ротации может не соответствовать ожидаемому.112113Новое в версии 3.3.114115#### `rotator`116117Если этому атрибуту присвоен вызываемый объект, метод [`rotate()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.BaseRotatingHandler.rotate) делегирует вызов этому объекту. Параметры, передаваемые вызываемому объекту, – это те же параметры, что передаются методу [`rotate()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.BaseRotatingHandler.rotate).118119Новое в версии 3.3.120121#### `rotation_filename(default_name)`122123Изменяет имя файла журнала при ротации.124125Это предусмотрено, чтобы можно было задать пользовательское имя файла.126127Реализация по умолчанию вызывает атрибут 'namer' обработчика, если он является вызываемым, передавая ему имя по умолчанию. Если атрибут не является вызываемым (по умолчанию `None`), имя возвращается без изменений.128129| Параметры: | **default\_name** – имя файла журнала по умолчанию. |130| --- | --- |131132Новое в версии 3.3.133134#### `rotate(source, dest)`135136При ротации выполняет ротацию текущего журнала.137138Реализация по умолчанию вызывает атрибут 'rotator' обработчика, если он является вызываемым, передавая ему аргументы source и dest. Если атрибут не является вызываемым (по умолчанию `None`), файл source просто переименовывается в destination.139140| Параметры: | **source** – исходное имя файла. Обычно это базовое имя файла, например ‘test.log’. **dest** – имя файла назначения. Обычно это то, во что ротируется source, например ‘test.log.1’. |141| --- | --- |142143Новое в версии 3.3.144145Атрибуты существуют для того, чтобы избавить от необходимости создавать подклассы: можно использовать одни и те же вызываемые объекты для экземпляров [`RotatingFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.RotatingFileHandler) и [`TimedRotatingFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler). Если какой-либо из вызываемых объектов namer или rotator возбуждает исключение, оно обрабатывается так же, как любое другое исключение при вызове `emit()`, то есть через метод `handleError()` обработчика.146147Если требуется внести более существенные изменения в обработку ротации, можно переопределить методы.148149Пример см. в [*Использование rotator и namer для настройки обработки ротации журналов*](https://python-all.ru/3.4/howto/logging-cookbook.html#cookbook-rotator-namer).150151## 16.8.6. RotatingFileHandler152153Класс [`RotatingFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.RotatingFileHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), поддерживает ротацию файлов журнала на диске.154155#### `class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0)`156157Возвращает новый экземпляр класса [`RotatingFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.RotatingFileHandler). Указанный файл открывается и используется как поток для журналирования. Если *mode* не указан, используется `'a'`. Если *encoding* не равен *None*, файл открывается с указанной кодировкой. Если *delay* равен истине, открытие файла откладывается до первого вызова [`emit()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.RotatingFileHandler.emit). По умолчанию файл растёт бесконечно.158159You can use the *maxBytes* and *backupCount* values to allow the file to *rollover* at a predetermined size. When the size is about to be exceeded, the file is closed and a new file is silently opened for output. Rollover occurs whenever the current log file is nearly *maxBytes* in length; if either of *maxBytes* or *backupCount* is zero, rollover never occurs. If *backupCount* is non-zero, the system will save old log files by appending the extensions ‘.1’, ‘.2’ etc., to the filename. For example, with a *backupCount* of 5 and a base file name of `app.log`, you would get `app.log`, `app.log.1`, `app.log.2`, up to `app.log.5`. The file being written to is always `app.log`. When this file is filled, it is closed and renamed to `app.log.1`, and if files `app.log.1`, `app.log.2`, etc. exist, then they are renamed to `app.log.2`, `app.log.3` etc. respectively.160161#### `doRollover()`162163Выполняет ротацию, как описано выше.164165#### `emit(record)`166167Записывает запись (record) в файл, выполняя при необходимости ротацию, как описано ранее.168169## 16.8.7. TimedRotatingFileHandler170171Класс [`TimedRotatingFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), поддерживает ротацию файлов журнала на диске через заданные интервалы времени.172173#### `class logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None)`174175Возвращает новый экземпляр класса [`TimedRotatingFileHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler). Указанный файл открывается и используется как поток для журналирования. При ротации также устанавливается суффикс имени файла. Ротация происходит на основе произведения *when* и *interval*.176177Параметр *when* указывает тип *interval*. Список возможных значений приведён ниже. Обратите внимание, что регистр не учитывается.178179| Значение | Тип интервала |180| --- | --- |181| `'S'` | Секунды |182| `'M'` | Минуты |183| `'H'` | Часы |184| `'D'` | Дни |185| `'W0'-'W6'` | День недели (0=понедельник) |186| `'midnight'` | Переключение в полночь |187188При использовании ротации по дням недели укажите 'W0' для понедельника, 'W1' для вторника и так далее до 'W6' для воскресенья. В этом случае значение, переданное для *interval*, не используется.189190Система будет сохранять старые файлы журнала, добавляя расширения к имени файла. Расширения основаны на дате и времени, с использованием формата strftime `%Y-%m-%d_%H-%M-%S` или его начальной части, в зависимости от интервала ротации.191192При первом вычислении времени следующей ротации (при создании обработчика) используется время последнего изменения существующего файла журнала или, в противном случае, текущее время, чтобы определить, когда произойдёт следующая ротация.193194Если аргумент *utc* равен true, используется время в UTC; в противном случае используется местное время.195196Если *backupCount* не равен нулю, сохраняется не более *backupCount* файлов; если при ротации должно быть создано больше файлов, самый старый удаляется. Логика удаления использует интервал для определения того, какие файлы нужно удалить, поэтому изменение интервала может привести к тому, что старые файлы останутся.197198Если *delay* равен true, открытие файла откладывается до первого вызова [`emit()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler.emit).199200Если *atTime* не равен `None`, он должен быть экземпляром `datetime.time`, который задает время суток, когда происходит переключение, для случаев, когда переключение должно происходить «в полночь» или «в определенный день недели».201202Изменено в версии 3.4: Добавлен параметр *atTime*.203204#### `doRollover()`205206Выполняет ротацию, как описано выше.207208#### `emit(record)`209210Выводит запись в файл, обеспечивая ротацию, как описано выше.211212## 16.8.8. SocketHandler213214Класс [`SocketHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SocketHandler), находящийся в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), отправляет вывод журнала в сетевой сокет. Базовый класс использует TCP-сокет.215216#### `class logging.handlers.SocketHandler(host, port)`217218Возвращает новый экземпляр класса [`SocketHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SocketHandler), предназначенного для взаимодействия с удаленной машиной, адрес которой задается *host* и *port*.219220Изменено в версии 3.4: Если `port` указан как `None`, создается доменный сокет Unix с использованием значения `host` – в противном случае создается TCP-сокет.221222#### `close()`223224Закрывает сокет.225226#### `emit()`227228Сериализует словарь атрибутов записи и записывает его в сокет в dвоичном формате. Если возникла ошибка с сокетом, пакет молча отбрасывается. Если соединение было ранее потеряно, восстанавливает его. Чтобы десериализовать запись на принимающей стороне в объект [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord), используйте функцию [`makeLogRecord()`](https://python-all.ru/3.4/library/logging.html#logging.makeLogRecord).229230#### `handleError()`231232Обрабатывает ошибку, возникшую во время [`emit()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SocketHandler.emit). Наиболее вероятная причина – потеря соединения. Закрывает сокет, чтобы можно было повторить попытку при следующем событии.233234#### `makeSocket()`235236Это фабричный метод, позволяющий подклассам определять точный тип сокета, который они хотят. Реализация по умолчанию создает TCP-сокет ([`socket.SOCK_STREAM`](https://python-all.ru/3.4/library/socket.html#socket.SOCK_STREAM)).237238#### `makePickle(record)`239240Сериализует словарь атрибутов записи в двоичном формате с префиксом длины и возвращает его готовым к передаче через сокет.241242Обратите внимание, что модуль pickle не является полностью безопасным. Если вас беспокоит безопасность, вы можете переопределить этот метод, чтобы реализовать более надёжный механизм. Например, можно подписывать данные с помощью HMAC и проверять подпись на принимающей стороне, либо отключить десериализацию глобальных объектов на принимающей стороне.243244#### `send(packet)`245246Отправляет сериализованную с помощью pickle строку *packet* в сокет. Эта функция допускает частичную отправку, которая может произойти, когда сеть занята.247248#### `createSocket()`249250Пытается создать сокет; в случае неудачи применяет алгоритм экспоненциальной отсрочки. При первой неудаче обработчик отбрасывает сообщение, которое пытался отправить. Когда последующие сообщения обрабатываются тем же экземпляром, он не будет пытаться установить соединение, пока не пройдёт некоторое время. Значения параметров по умолчанию таковы, что начальная задержка составляет одну секунду, и если после этой задержки соединение всё ещё не может быть установлено, обработчик будет удваивать задержку каждый раз вплоть до максимума в 30 секунд.251252Это поведение управляется следующими атрибутами обработчика:253254- `retryStart` (начальная задержка, по умолчанию 1.0 секунды).255- `retryFactor` (множитель, по умолчанию 2.0).256- `retryMax` (максимальная задержка, по умолчанию 30.0 секунд).257258Это означает, что если удалённый слушатель запускается *после* того, как обработчик уже использовался, возможна потеря сообщений (поскольку обработчик даже не будет пытаться установить соединение, пока не истечёт задержка, а будет просто молча отбрасывать сообщения в течение этого периода).259260## 16.8.9. DatagramHandler261262Класс [`DatagramHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.DatagramHandler), находящийся в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), наследует от [`SocketHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SocketHandler) для поддержки отправки сообщений журнала через UDP-сокеты.263264#### `class logging.handlers.DatagramHandler(host, port)`265266Возвращает новый экземпляр класса [`DatagramHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.DatagramHandler), предназначенного для взаимодействия с удаленной машиной, адрес которой задается *host* и *port*.267268Изменено в версии 3.4: Если `port` указан как `None`, создается доменный сокет Unix с использованием значения `host` – в противном случае создается TCP-сокет.269270#### `emit()`271272Сериализует словарь атрибутов записи и записывает его в сокет в dвоичном формате. Если возникла ошибка с сокетом, пакет молча отбрасывается. Чтобы десериализовать запись на принимающей стороне в объект [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord), используйте функцию [`makeLogRecord()`](https://python-all.ru/3.4/library/logging.html#logging.makeLogRecord).273274#### `makeSocket()`275276Фабричный метод [`SocketHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SocketHandler) здесь переопределен для создания UDP-сокета ([`socket.SOCK_DGRAM`](https://python-all.ru/3.4/library/socket.html#socket.SOCK_DGRAM)).277278#### `send(s)`279280Отправляет сериализованную с помощью pickle строку в сокет.281282## 16.8.10. SysLogHandler283284Класс [`SysLogHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SysLogHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), поддерживает отправку сообщений журнала на удалённый или локальный syslog Unix.285286#### `class logging.handlers.SysLogHandler(address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM)`287288Возвращает новый экземпляр класса [`SysLogHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SysLogHandler), предназначенного для взаимодействия с удалённой Unix-машиной, чей адрес задаётся *address* в виде кортежа `(host, port)`. Если *address* не указан, используется `('localhost', 514)`. Адрес используется для открытия сокета. Альтернативой предоставлению кортежа `(host, port)` является передача адреса в виде строки, например ‘/dev/log’. В этом случае для отправки сообщения syslog используется сокет домена Unix. Если *facility* не указан, используется `LOG_USER`. Тип открываемого сокета зависит от аргумента *socktype*, который по умолчанию равен [`socket.SOCK_DGRAM`](https://python-all.ru/3.4/library/socket.html#socket.SOCK_DGRAM) и, таким образом, открывает UDP-сокет. Чтобы открыть TCP-сокет (для использования с более новыми демонами syslog, такими как rsyslog), укажите значение [`socket.SOCK_STREAM`](https://python-all.ru/3.4/library/socket.html#socket.SOCK_STREAM).289290Обратите внимание: если ваш сервер не слушает UDP-порт 514, [`SysLogHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SysLogHandler) может не работать. В этом случае проверьте, какой адрес следует использовать для сокета домена – это зависит от системы. Например, в Linux это обычно ‘/dev/log’, а в OS/X – ‘/var/run/syslog’. Вам нужно проверить свою платформу и использовать соответствующий адрес (возможно, придётся делать эту проверку во время выполнения, если приложение должно работать на нескольких платформах). В Windows практически приходится использовать опцию UDP.291292Изменено в версии 3.2: добавлен параметр *socktype*.293294#### `close()`295296Закрывает сокет, подключённый к удалённому узлу.297298#### `emit(record)`299300Запись форматируется и отправляется на сервер syslog. Если присутствует информация об исключении, она *не* отправляется на сервер.301302Изменено в версии 3.2.1: (См.: [issue 12168](https://python-all.ru/3.4/library/logging.handlers.html).) В более ранних версиях сообщение, отправляемое демонам syslog, всегда завершалось NUL-байтом, поскольку ранние версии этих демонов ожидали сообщение с завершающим NUL – хотя это не предусмотрено соответствующей спецификацией (RFC 5424). Более новые версии этих демонов не ожидают NUL-байт, но удаляют его, если он присутствует, а ещё более новые демоны (которые точнее следуют RFC 5424) передают NUL-байт как часть сообщения.303304Чтобы упростить обработку сообщений syslog в условиях столь разного поведения демонов, добавление NUL-байта было сделано настраиваемым с помощью атрибута уровня класса `append_nul`. По умолчанию он равен `True` (сохраняя существующее поведение), но может быть установлен в `False` на экземпляре `SysLogHandler`, чтобы этот экземпляр *не* добавлял завершающий NUL.305306Изменено в версии 3.3: (См.: [issue 12419](https://python-all.ru/3.4/library/logging.handlers.html).) В более ранних версиях не было возможности указать префикс “ident” или “tag” для идентификации источника сообщения. Теперь его можно задать с помощью атрибута уровня класса, по умолчанию `""` для сохранения существующего поведения, но который может быть переопределён на экземпляре `SysLogHandler`, чтобы этот экземпляр добавлял идентификатор к каждому обработанному сообщению. Обратите внимание, что указанный идентификатор должен быть текстом, не байтами, и добавляется к сообщению как есть.307308#### `encodePriority(facility, priority)`309310Кодирует средство и приоритет в целое число. Можно передавать строки или целые числа – если передаются строки, внутренние словари сопоставлений используются для преобразования их в целые числа.311312Символические значения `LOG_` определены в [`SysLogHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SysLogHandler) и соответствуют значениям, определённым в заголовочном файле `sys/syslog.h`.313314**Приоритеты**315316| Имя (строка) | Символическое значение |317| --- | --- |318| `alert` | LOG\_ALERT |319| `crit` or `critical` | LOG\_CRIT |320| `debug` | LOG\_DEBUG |321| `emerg` or `panic` | LOG\_EMERG |322| `err` or `error` | LOG\_ERR |323| `info` | LOG\_INFO |324| `notice` | LOG\_NOTICE |325| `warn` or `warning` | LOG\_WARNING |326327**Средства**328329| Имя (строка) | Символическое значение |330| --- | --- |331| `auth` | LOG\_AUTH |332| `authpriv` | LOG\_AUTHPRIV |333| `cron` | LOG\_CRON |334| `daemon` | LOG\_DAEMON |335| `ftp` | LOG\_FTP |336| `kern` | LOG\_KERN |337| `lpr` | LOG\_LPR |338| `mail` | LOG\_MAIL |339| `news` | LOG\_NEWS |340| `syslog` | LOG\_SYSLOG |341| `user` | LOG\_USER |342| `uucp` | LOG\_UUCP |343| `local0` | LOG\_LOCAL0 |344| `local1` | LOG\_LOCAL1 |345| `local2` | LOG\_LOCAL2 |346| `local3` | LOG\_LOCAL3 |347| `local4` | LOG\_LOCAL4 |348| `local5` | LOG\_LOCAL5 |349| `local6` | LOG\_LOCAL6 |350| `local7` | LOG\_LOCAL7 |351352#### `mapPriority(levelname)`353354Сопоставляет имя уровня логирования с именем приоритета syslog. Возможно, потребуется переопределить это, если используются пользовательские уровни, или если алгоритм по умолчанию не подходит. Алгоритм по умолчанию сопоставляет `DEBUG`, `INFO`, `WARNING`, `ERROR` и `CRITICAL` с соответствующими именами syslog, а все остальные уровни сопоставляет с 'warning'.355356## 16.8.11. NTEventLogHandler357358Класс [`NTEventLogHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.NTEventLogHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers) модуле, поддерживает отправку сообщений логирования в журнал событий локальной системы Windows NT, Windows 2000 или Windows XP. Перед использованием необходимо установить расширения Win32 для Python от Mark Hammond.359360#### `class logging.handlers.NTEventLogHandler(appname, dllname=None, logtype='Application')`361362Возвращает новый экземпляр класса [`NTEventLogHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.NTEventLogHandler). Параметр *appname* используется для определения имени приложения, отображаемого в журнале событий. С использованием этого имени создается соответствующая запись реестра. Параметр *dllname* должен содержать полный путь к .dll или .exe-файлу с определениями сообщений для хранения в журнале (если не указан, используется `'win32service.pyd'` – он устанавливается вместе с расширениями Win32 и содержит несколько базовых определений сообщений-заполнителей. Обратите внимание, что использование этих заполнителей приведет к увеличению размера журнала, так как весь источник сообщений хранится в журнале. Если нужны более компактные журналы, следует передать имя собственного .dll или .exe, содержащего нужные определения сообщений). Параметр *logtype* может быть одним из `'Application'`, `'System'` или `'Security'`, по умолчанию `'Application'`.363364#### `close()`365366На этом этапе можно удалить имя приложения из реестра как источник записей журнала событий. Однако после этого события не будут отображаться в средстве просмотра журнала событий так, как предполагалось – для получения имени .dll требуется доступ к реестру. Текущая версия этого не делает.367368#### `emit(record)`369370Определяет идентификатор сообщения, категорию и тип события, а затем записывает сообщение в журнал событий NT.371372#### `getEventCategory(record)`373374Возвращает категорию события для записи. Переопределите этот метод, чтобы указать собственные категории. Данная версия возвращает 0.375376#### `getEventType(record)`377378Возвращает тип события для записи. Переопределите этот метод, если нужно задать собственные типы. В данной версии используется сопоставление через атрибут typemap обработчика, который устанавливается в [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) в виде словаря, содержащего сопоставления для `DEBUG`, `INFO`, `WARNING`, `ERROR` и `CRITICAL`. При использовании собственных уровней потребуется либо переопределить этот метод, либо поместить подходящий словарь в атрибут *typemap* обработчика.379380#### `getMessageID(record)`381382Возвращает идентификатор сообщения для записи. При использовании собственных сообщений можно передать в логгер идентификатор *msg* вместо строки форматирования. Затем здесь можно выполнить поиск по словарю для получения идентификатора сообщения. Данная версия возвращает 1 – базовый идентификатор сообщения в `win32service.pyd`.383384## 16.8.12. SMTPHandler385386Класс [`SMTPHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SMTPHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), поддерживает отправку сообщений логирования на адрес электронной почты через SMTP.387388#### `class logging.handlers.SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None, timeout=1.0)`389390Возвращает новый экземпляр класса [`SMTPHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SMTPHandler). Экземпляр инициализируется адресами отправителя, получателя и темой письма. Параметр *toaddrs* должен быть списком строк. Для указания нестандартного порта SMTP используется кортеж (host, port) в аргументе *mailhost*. Если передана строка, используется стандартный порт SMTP. Если SMTP-сервер требует аутентификации, можно указать кортеж (username, password) в аргументе *credentials*.391392Для использования защищенного протокола (TLS) передайте кортеж в аргумент *secure*. Это будет работать только при наличии учетных данных для аутентификации. Кортеж должен быть либо пустым, либо содержать один элемент – имя файла ключа, либо два элемента – имена файла ключа и сертификата. (Этот кортеж передается методу [`smtplib.SMTP.starttls()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.starttls).)393394Для взаимодействия с SMTP-сервером можно задать тайм-аут с помощью аргумента *timeout*.395396Новое в версии 3.3: Аргумент *timeout* был добавлен.397398#### `emit(record)`399400Форматирует запись и отправляет её указанным получателям.401402#### `getSubject(record)`403404Чтобы задать тему письма, зависящую от записи, переопределите этот метод.405406## 16.8.13. MemoryHandler407408Класс [`MemoryHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.MemoryHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), поддерживает буферизацию записей логирования в памяти с периодической отправкой в целевой обработчик *target*. Сброс происходит, когда буфер заполнен или когда встречается событие определенного уровня серьезности или выше.409410[`MemoryHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.MemoryHandler) является подклассом более общего [`BufferingHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.BufferingHandler), который является абстрактным классом. Он буферизует записи логирования в памяти. При добавлении каждой записи в буфер вызывается `shouldFlush()` для проверки необходимости сброса. Если сброс требуется, то ожидается, что `flush()` выполнит сброс.411412#### `class logging.handlers.BufferingHandler(capacity)`413414Инициализирует обработчик буфером указанной ёмкости.415416#### `emit(record)`417418Добавляет запись в буфер. Если [`shouldFlush()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.BufferingHandler.shouldFlush) возвращает true, вызывает [`flush()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.BufferingHandler.flush) для обработки буфера.419420#### `flush()`421422Вы можете переопределить этот метод, чтобы задать собственное поведение при сбросе. Текущая версия просто очищает буфер.423424#### `shouldFlush(record)`425426Возвращает true, если буфер заполнен до ёмкости. Этот метод можно переопределить для реализации собственных стратегий сброса.427428#### `class logging.handlers.MemoryHandler(capacity, flushLevel=ERROR, target=None)`429430Возвращает новый экземпляр класса [`MemoryHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.MemoryHandler). Экземпляр инициализируется с размером буфера *capacity*. Если *flushLevel* не указан, используется `ERROR`. Если *target* не указан, перед тем как обработчик начнёт работать, цель нужно задать с помощью [`setTarget()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.MemoryHandler.setTarget).431432#### `close()`433434Вызывает [`flush()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.MemoryHandler.flush), устанавливает цель в `None` и очищает буфер.435436#### `flush()`437438Для [`MemoryHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.MemoryHandler) сброс означает просто отправку буферизованных записей целевому обработчику, если он есть. Буфер также очищается, когда это происходит. Переопределите, если нужно иное поведение.439440#### `setTarget(target)`441442Устанавливает целевой обработчик для данного обработчика.443444#### `shouldFlush(record)`445446Проверяет, заполнен ли буфер или поступила запись уровня *flushLevel* или выше.447448## 16.8.14. HTTPHandler449450Класс [`HTTPHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.HTTPHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), поддерживает отправку сообщений журнала на веб-сервер с использованием семантики `GET` или `POST`.451452#### `class logging.handlers.HTTPHandler(host, url, method='GET', secure=False, credentials=None, context=None)`453454Returns a new instance of the [`HTTPHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.HTTPHandler) class. The *host* can be of the form `host:port`, should you need to use a specific port number. If no *method* is specified, `GET` is used. If *secure* is true, a HTTPS connection will be used. The *context* parameter may be set to a [`ssl.SSLContext`](https://python-all.ru/3.4/library/ssl.html#ssl.SSLContext) instance to configure the SSL settings used for the HTTPS connection. If *credentials* is specified, it should be a 2-tuple consisting of userid and password, which will be placed in a HTTP ‘Authorization’ header using Basic authentication. If you specify credentials, you should also specify secure=True so that your userid and password are not passed in cleartext across the wire.455456Изменено в версии 3.4.3: Был добавлен параметр *context*.457458#### `mapLogRecord(record)`459460Предоставляет словарь на основе `record`, который будет URL-закодирован и отправлен на веб-сервер. Реализация по умолчанию просто возвращает `record.__dict__`. Этот метод можно переопределить, если, например, на веб-сервер нужно отправлять только подмножество [`LogRecord`](https://python-all.ru/3.4/library/logging.html#logging.LogRecord), или требуется более точная настройка того, что отправляется на сервер.461462#### `emit(record)`463464Отправляет запись на веб-сервер в виде URL-закодированного словаря. Метод [`mapLogRecord()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.HTTPHandler.mapLogRecord) используется для преобразования записи в словарь для отправки.465466> **Примечание**467>468> Поскольку подготовка записи для отправки на веб-сервер не является обычной операцией форматирования, использование [`setFormatter()`](https://python-all.ru/3.4/library/logging.html#logging.Handler.setFormatter) для указания [`Formatter`](https://python-all.ru/3.4/library/logging.html#logging.Formatter) для [`HTTPHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.HTTPHandler) не имеет эффекта. Вместо вызова [`format()`](https://python-all.ru/3.4/library/logging.html#logging.Handler.format) этот обработчик вызывает [`mapLogRecord()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.HTTPHandler.mapLogRecord), а затем [`urllib.parse.urlencode()`](https://python-all.ru/3.4/library/urllib.parse.html#urllib.parse.urlencode) для кодирования словаря в форму, пригодную для отправки на веб-сервер.469470## 16.8.15. QueueHandler471472Новое в версии 3.2.473474Класс [`QueueHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueHandler), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers), поддерживает отправку сообщений журнала в очередь, например, реализованную в модулях [`queue`](https://python-all.ru/3.4/library/queue.html#module-queue) или [`multiprocessing`](https://python-all.ru/3.4/library/multiprocessing.html#module-multiprocessing).475476Вместе с классом [`QueueListener`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueListener) [`QueueHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueHandler) можно использовать, чтобы обработчики выполняли свою работу в отдельном потоке, отличном от того, который ведёт журналирование. Это важно в веб-приложениях и других служебных приложениях, где потоки, обслуживающие клиентов, должны отвечать как можно быстрее, в то время как потенциально медленные операции (например, отправка электронной почты через [`SMTPHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SMTPHandler)) выполняются в отдельном потоке.477478#### `class logging.handlers.QueueHandler(queue)`479480Возвращает новый экземпляр класса [`QueueHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueHandler). Экземпляр инициализируется очередью для отправки сообщений. Очередью может быть любой объект, похожий на очередь; он используется как есть методом [`enqueue()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueHandler.enqueue), который должен знать, как отправлять в неё сообщения.481482#### `emit(record)`483484Помещает в очередь результат подготовки LogRecord.485486#### `prepare(record)`487488Подготавливает запись для помещения в очередь. Объект, возвращаемый этим методом, помещается в очередь.489490Базовая реализация форматирует запись, объединяя сообщение и аргументы, и удаляет несериализуемые элементы из записи на месте.491492Этот метод можно переопределить, если требуется преобразовать запись в словарь или JSON-строку, или отправить изменённую копию записи, оставив оригинал нетронутым.493494#### `enqueue(record)`495496Помещает запись в очередь с помощью `put_nowait()`; этот метод можно переопределить, если требуется блокирующее поведение, или тайм-аут, или собственная реализация очереди.497498## 16.8.16. QueueListener499500Новое в версии 3.2.501502Класс [`QueueListener`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueListener), расположенный в модуле [`logging.handlers`](https://python-all.ru/3.4/library/logging.handlers.html#module-logging.handlers) , поддерживает получение сообщений журнала из очереди, например, реализованной в модулях [`queue`](https://python-all.ru/3.4/library/queue.html#module-queue) или [`multiprocessing`](https://python-all.ru/3.4/library/multiprocessing.html#module-multiprocessing). Сообщения получаются из очереди во внутреннем потоке и передаются, в том же потоке, одному или нескольким обработчикам для обработки. Хотя [`QueueListener`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueListener) сам по себе не является обработчиком, он документирован здесь, поскольку работает в тесной связке с [`QueueHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueHandler).503504Вместе с классом [`QueueHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueHandler) [`QueueListener`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueListener) можно использовать, чтобы обработчики выполняли свою работу в отдельном потоке, отличном от того, который ведёт журналирование. Это важно в веб-приложениях и других служебных приложениях, где потоки, обслуживающие клиентов, должны отвечать как можно быстрее, в то время как потенциально медленные операции (например, отправка электронной почты через [`SMTPHandler`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.SMTPHandler)) выполняются в отдельном потоке.505506#### `class logging.handlers.QueueListener(queue, *handlers)`507508Возвращает новый экземпляр класса [`QueueListener`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueListener). Экземпляр инициализируется очередью для отправки сообщений и списком обработчиков, которые будут обрабатывать записи, помещенные в очередь. Очередью может быть любой объект, похожий на очередь; он передается как есть методу [`dequeue()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueListener.dequeue), который должен знать, как получать из неё сообщения.509510#### `dequeue(block)`511512Извлекает запись из очереди и возвращает её, опционально блокируя.513514Базовая реализация использует `get()`. Возможно, потребуется переопределить этот метод, если нужно использовать тайм-ауты или работать с нестандартными реализациями очередей.515516#### `prepare(record)`517518Подготавливает запись к обработке.519520Эта реализация просто возвращает переданную запись. Можно переопределить этот метод, если требуется выполнить какую-либо собственную маршалинг или манипуляцию записью перед передачей обработчикам.521522#### `handle(record)`523524Обрабатывает запись.525526Этот метод просто перебирает обработчики, предлагая им запись для обработки. Объект, фактически передаваемый обработчикам, – это тот, который возвращается из [`prepare()`](https://python-all.ru/3.4/library/logging.handlers.html#logging.handlers.QueueListener.prepare).527528#### `start()`529530Запускает прослушиватель.531532Запускает фоновый поток для отслеживания очереди на предмет LogRecords, которые нужно обработать.533534#### `stop()`535536Останавливает прослушиватель.537538Запрашивает завершение потока и затем ожидает его завершения. Обратите внимание: если не вызвать этот метод до завершения приложения, в очереди могут остаться некоторые записи, которые не будут обработаны.539540#### `enqueue_sentinel()`541542Записывает сторожевой элемент в очередь, чтобы сообщить слушателю о завершении. В данной реализации используется `put_nowait()`. Возможно, потребуется переопределить этот метод, если нужно использовать тайм-ауты или работать с нестандартными реализациями очередей.543544Новое в версии 3.3.545546> **См. также**547>548> **Модуль [`logging`](https://python-all.ru/3.4/library/logging.html#module-logging)**549>550> Справочник API для модуля logging.551>552> **Модуль [`logging.config`](https://python-all.ru/3.4/library/logging.config.html#module-logging.config)**553>554> API конфигурации для модуля logging.555