Использует ли python logging.FileHandler по умолчанию блочную буферизацию? - PullRequest
2 голосов
/ 10 апреля 2019

Классы обработчиков logging имеют метод flush ().

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

Это правильно?


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


Меня интересуют последние версии Python: 2.7 и 3.7.

(И, возможно, недавняя история. Любой ответ, который ссылается на предложенный патч, будет сильным соперником :-). Некоторые мнения могут быть уместны здесь, потому что я не очень опытный).

1 Ответ

0 голосов
/ 11 апреля 2019

Не совсем.Он сбрасывает каждое отдельное сообщение, что вам и нужно.

FileHandler наследуется от StreamHandler.StreamHandler вызывает self.flush () после каждой записи () в поток.

Метод flush () начинает приобретать больше смысла, если вы посмотрите на logging.MemoryHandler.Для программ, которые хотят добавить буферизацию, MemoryHandler позволяет обернуть другой обработчик и буферизовать определенное количество сообщений.Он также немедленно сбрасывается в сообщениях выше установленного уровня серьезности.logging не включает обработчик, который автоматически сбрасывает каждую секунду или около того, но вы всегда можете написать его самостоятельно.

Сброс вызовов в StreamHandler также означает, что он делает то, что вы хотите,если ваша программа запущена как systemd служба и вы регистрируетесь на stderr.В этом случае Python 3 требует сброса.Python 3 в настоящее время использует блочную буферизацию для stderr, когда это не TTY.См. обсуждение проблемы Python 13597

Возможная причина моей ошибки

Я думаю, что меня смутил код StreamHandler.Если пользователю никогда не требовалось вызывать метод flush (), зачем StreamHandler определять непустую, публично документированную реализацию?

Я думаю, что предполагал слишком много, и я не учел наследование (argh) используется здесь.Например, базовый класс Handler имеет пустой метод flush (), но StreamHandler не хочет наследовать его, потому что у него странная строка документации «Эта версия ничего не делает и предназначена для реализации подклассами».

...