Python拖尾logfile sleep()与inotify?

2024-10-03 13:27:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个Python脚本,它需要tail -f一个日志文件。在

操作系统是RHEL,运行Linux2.6.18。在

我认为通常的方法是使用带有sleep的无限循环来不断地轮询文件。在

但是,由于我们使用的是Linux,我想我也可以使用pyinotify(https://github.com/seb-m/pyinotify)或Watchdog(https://github.com/gorakhargosh/watchdog)之类的东西来代替?在

这有什么利弊?在

我听说使用sleep(),如果文件增长很快,您可能会错过事件-这可能吗?我以为GNU tail也用睡眠呢?在

干杯, 维克托


Tags: 文件方法httpsgithub脚本comlinuxsleep
1条回答
网友
1楼 · 发布于 2024-10-03 13:27:31

最干净的解决方案在很多方面都是无效的——毕竟,这或多或少正是它的目的。如果日志文件的更改非常迅速,那么您可能会有几乎经常被唤醒的风险,这不一定特别有效—但是,您可以通过在inotify filehandle返回事件后添加自己的短延迟来减轻这种风险。在实践中,我怀疑这在大多数系统上会是一个问题,但我认为值得一提的情况下,您的系统是非常紧张的CPU资源。在

我看不出sleep()方法如何会错过文件更新,除非文件被截断或旋转(即重命名并创建了另一个同名文件)。不管你怎么做,这些都是很棘手的问题,你可以使用一些技巧,比如定期按名称重新打开文件来检查旋转。请阅读tail手册页,因为它处理许多这样的情况,而且它们对于日志文件来说非常常见(日志轮换被广泛认为是一种良好的实践)。在

sleep()的缺点当然是,您最终会在两个时间段之间延迟批处理您的读操作,而且即使文件没有更改,您也有不断唤醒和轮询文件的开销。但是,如果您这样做,比如说,每秒一次,那么在大多数系统上,开销可能并不明显。在

我认为inotify是最好的选择,除非您想保持兼容,在这种情况下,使用sleep()的简单回退仍然是相当合理的。在

编辑:

我刚刚意识到我忘了提一下-一个检查被重命名文件的简单方法是对打开的文件句柄执行os.fstat(fd.fileno()),对打开的文件名执行os.stat(),然后比较结果。如果os.stat()失败,则错误将告诉您文件是否已被删除,如果没有,则比较st_ino(inode编号)字段将告诉您该文件是否已被删除,然后替换为同名的新文件。在

检测截断比较困难-实际上,你的读取指针在文件中保持相同的偏移量,在文件内容大小恢复到原来的位置之前,读取不会返回任何内容-然后文件将正常从该点读取。如果您经常调用os.stat(),您可以检查文件大小是否向后移动—或者您可以使用fd.tell()来记录您在文件中的当前位置,然后对文件的结尾执行显式查找并再次调用fd.tell()。如果该值较低,则该文件将被截断。这是一个安全的操作,只要你保持原来的文件位置,因为你总是可以在检查后找到它。在

或者,如果您仍在使用inotify,您可以只查看父目录中的更改。在

请注意,文件可以被截断为非零大小,但我怀疑日志文件是否可能发生这种情况—常见的情况将被删除并替换,或者被截断为零。另外,我不知道你如何检测到文件被截断,然后立即填充到你当前位置之外的情况,除了记住最近的N个字符并进行比较,但这是一件相当糟糕的事情。我想inotify会告诉你在这种情况下文件已经被修改了。在

相关问题 更多 >