我正在编写一个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也用睡眠呢?在
干杯, 维克托
最干净的解决方案在很多方面都是无效的——毕竟,这或多或少正是它的目的。如果日志文件的更改非常迅速,那么您可能会有几乎经常被唤醒的风险,这不一定特别有效—但是,您可以通过在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会告诉你在这种情况下文件已经被修改了。在
相关问题 更多 >
编程相关推荐