【发布时间】:2023-03-10 10:29:02
【问题描述】:
我打算创建一个程序,该程序可以永久跟踪大量动态日志文件,将它们的条目复制到数据库中,以便更轻松地进行近实时统计。日志文件由不同的守护进程和应用程序编写,但它们的格式是已知的,因此可以对其进行解析。一些守护进程每天将日志写入一个文件,例如 Apache 的 cronolog 会创建像 access.20100928 这样的文件。这些文件在新的一天出现,并可能在第二天被压缩时消失。
目标平台是 64 位 Ubuntu 服务器。
高效读取这些日志文件的最佳方法是什么?
我可以想到像 PHP 这样的脚本语言,它们要么自己打开文件并读取新数据,要么使用像 tail -f 这样的系统工具来跟踪日志,或者像 Mono 这样的其他运行时。 Bash shell 脚本可能不太适合解析日志行并将它们插入数据库服务器 (MySQL),更不用说我的应用程序的简单配置了。
如果我的程序将读取日志文件,我认为它应该在一秒钟左右对文件进行一次 stat() 以获取其大小并在文件增长时打开文件。读取文件后(希望只返回完整的行),它可以调用 tell() 来获取当前位置,下一次直接 seek() 到保存的位置继续读取。 (这些是 C 函数名称,但实际上我不想在 C 中这样做。Mono/.NET 或 PHP 也提供类似的函数。)
文件的持续 stat()ing 以及随后的打开和关闭是否存在问题? tail -f 会怎么做呢?我可以让文件保持打开状态并通过 select() 之类的方式收到有关新数据的通知吗?还是总是在文件末尾返回?
如果我被某种 select() 或外部尾部阻塞,我需要每隔 1、2 分钟中断一次以扫描应该(不再)跟踪的新文件或已删除文件。使用 tail -f then 恢复可能不是很可靠。这应该更适合我自己保存的文件位置。
我可以为此使用某种 inotify(文件系统通知)吗?
【问题讨论】: