我正在开发一个需要进行日志记录的 Ruby 库。理想情况下,我希望多个工作进程能够登录到同一个文件。查看来自 Ruby 标准库的类的源代码,我看到正在努力将多个线程的写入同步到日志中(正如对Is Ruby's stdlib Logger class thread-safe?Logger
的回答所指出的那样)。
当多个进程写入同一个日志文件时,似乎存在类似的问题:根据底层决定缓冲/拆分写入的方式,每个日志消息可能无法保持其完整性。
那么,有没有办法使用标准Logger
类来允许多个进程安全地登录到单个文件?如果不是,这通常如何在 Ruby 项目中完成?
这就是我所说的“安全”的意思:
- 每个日志行都是“原子的”——完整地出现,在下一条消息开始之前不间断。例如,什么都不像
[1/1/2013 00:00:00] (PID N) LOGMESS[1/1/2013 00:00:01] (PID M) LOGMESSAGE2\nAGE1
- 日志消息不需要在进程之间严格排序,只要出现在日志中的时间戳是正确的。
更新:
我决定接受铁皮人的建议并编写一个测试,你可以在这里找到: https ://gist.github.com/4370423
简短版本:Winfield 是正确的,至少默认使用Logger
它可以安全地同时从多个进程中使用(对于上面给出的“安全”的定义)。
关键因素似乎是,如果给定文件路径(而不是已经打开的 IO 对象),Logger 将使用 mode 打开文件WRONLY|APPEND
,并sync=true
对其进行设置。这两件事的结合(至少在我在 Mac OS X 上的测试中)似乎可以安全地从多个进程同时登录。如果要传入一个已经打开的 IO 对象,只需确保以相同的方式创建它。