vic*_*ooi 1 python file-io tail
我正在编写一个需要tail -f日志文件的Python脚本.
操作系统是RHEL,运行Linux 2.6.18.
我认为通常的方法是使用带睡眠的无限循环来连续轮询文件.
但是,既然我们在Linux上,我想我也可以使用像pyinotify(https://github.com/seb-m/pyinotify)或Watchdog(https://github.com/gorakhargosh/watchdog)这样的东西.代替?
这有什么优点/缺点?
我听说使用sleep(),你可以错过事件,如果文件快速增长 - 这可能吗?我认为GNU尾部无论如何都会使用睡眠?
干杯,维克多
最干净的解决方案是以多种方式进行inotify - 毕竟,这或多或少完全符合它的目的.如果日志文件变化非常快,那么您可能会冒险被几乎不断地唤醒,这不一定特别有效 - 但是,您可以通过在inotify文件句柄返回事件后添加自己的短暂延迟来缓解此问题.在实践中,我怀疑这在大多数系统上都是一个问题,但我认为值得一提,以防你的系统CPU资源非常紧张.
我无法看到该sleep()方法如何丢失文件更新,除非文件被截断或旋转(即重命名和创建同名的另一个文件).这些是棘手的情况,无论你做什么都可以处理,你可以使用技巧,例如定期按名称重新打开文件以检查旋转.阅读tail手册页,因为它处理了许多这样的情况,特别是对于日志文件来说它们很常见(日志轮换被广泛认为是一种很好的做法).
sleep()当然,缺点是你最终会将读取与之间的延迟进行批处理,并且即使它没有改变,你也有不断唤醒和轮询文件的开销.但是,如果你这样做,比如每秒一次,那么在大多数系统上,开销可能并不明显.
我会说inotify是最好的选择,除非你想保持兼容,在这种情况下简单的后备使用sleep()仍然是非常合理的.
编辑:
我刚刚意识到我忘记提及了 - 检查重命名文件的一种简单方法是os.fstat(fd.fileno())在打开的文件句柄上执行a ,然后在打开的文件os.stat()名上执行,并比较结果.如果os.stat()失败,则错误将告诉您文件是否已被删除,如果没有,则比较st_ino(inode编号)字段将告诉您文件是否已被删除,然后替换为同名的新文件.
检测截断更难 - 有效的读指针保持在文件中的相同偏移量,并且读取将不返回任何内容,直到文件内容大小恢复到原来的位置 - 然后文件将从该点正常读取.如果您os.stat()经常拨打电话,可以检查文件大小是否倒退 - 或者您可以使用fd.tell()在文件中记录当前位置,然后在文件末尾执行显式搜索并fd.tell()再次调用.如果该值较低,则该文件在您下面被截断.只要您保留原始文件位置,这是一个安全的操作,因为您可以在检查后始终寻找它.
或者,如果您仍在使用inotify,则可以只查看父目录以进行更改.
请注意,文件可以被截断为非零大小,但我怀疑这可能发生在日志文件中 - 常见情况将被删除和替换,或截断为零.此外,我不知道你是如何检测文件被截断的情况,然后立即填充回到当前位置之外,除了记住最近的N个字符并比较它们,但这是一个非常难以理解的事情.做.我认为inotify只会告诉你该文件已被修改过.