Python的logging.FileHandler默认使用块缓冲吗?

7
logging处理程序类有一个flush()方法。
查看代码logging.FileHandler在调用open()时不传递特定的缓冲模式。因此,当您写入日志文件时,它将使用默认块大小进行缓冲。
这是否正确?
这让我感到惊讶,因为当我管理自己的系统时,我习惯于将日志文件作为系统上的实时(或准实时)视图进行查看。对于这种情况,需要行缓冲。此外,传统的syslog()到日志守护进程不会缓冲消息。
我对Python 2.7和3.7版本感兴趣。

当tty时,关于stderr的一个小提示是,它往往默认为无缓冲,而stdout通常默认为行缓冲。我不知道systemd/journald,但我认为将任何stderr捕获/重定向的缓冲更改为相同(无缓冲)是有意义的。 - Ondrej K.
@OndrejK。我的问题的答案是“不”,我读错了代码,我会写出来的。关于stderr的缓冲,我认为python3有令人惊讶的行为。我参考了文档,它说它可以是块缓冲,我认为文档是准确的。更多讨论请参见此python问题 - sourcejedi
是的,我查看了底层代码...在py2.7中,“a”模式基本上会执行您的系统对“openat”调用的任何操作。在py3.x中,“a”是文本模式,因此您将获得缓冲文本io(在非tty块上,默认情况下在tty行上),下面的文件句柄openat相同(除了|O_CLOEXEC,“不可继承”的fd),但缓冲来自io模块。 - Ondrej K.
1个回答

7
并不是真的。它将清除每个单独的消息,这正是您想要的。
FileHandler继承自StreamHandler。 StreamHandler在向流写入后调用self.flush()。
如果您查看logging.MemoryHandler,flush()方法开始变得更有意义。对于希望添加缓冲区的程序,MemoryHandler允许包装另一个处理程序,并缓冲一组消息。它还会立即刷新超过一定严重性级别的消息。logging没有包括自动每秒刷新一次或类似的处理程序,但您可以自己编写处理程序。
StreamHandler中的刷新调用也意味着,如果您的程序作为systemd服务运行并记录到stderr,则它做到了您想要的。Python 3在这种情况下需要刷新。当stderr不是TTY时,Python 3当前使用块缓冲。请参见Python问题13597上的讨论 我犯错的可能原因

我觉得我被StreamHandler的代码搞糊涂了。如果用户从未需要调用flush()方法,为什么StreamHandler要定义一个非空的、公开记录的实现呢?

我想我过于假设了,并没有考虑继承在这里是如何使用的(啊)。例如,基本的Handler类有一个空的flush()方法,但StreamHandler不想继承它,因为它有一个奇怪的文档字符串“This version does nothing and is intended to be implemented by subclasses”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接