Ruby的stdlib Logger类可以安全地处理来自多个进程的编写器吗?

时间:2012-12-17 05:27:40

标签: ruby logging

我正在开发一个需要进行日志记录的Ruby库。理想情况下,我希望多个工作进程能够登录到同一个文件。从Ruby的标准库中查看Logger类的源代码,我看到我们正努力将写入从多个线程同步到日志中(如Is Ruby's stdlib Logger class thread-safe?的答案中所指出的那样)。

当多个进程写入同一个日志文件时,似乎存在类似的问题:根据底层如何决定缓冲/拆分写入,每条日志消息可能无法保持其完整性。

那么,有没有办法使用标准Logger类来允许多个进程安全地登录到单个文件?如果没有,这通常如何在Ruby项目中完成?

这就是'安全'的意思:

  1. 每个日志行都是“原子” - 完整显示,在下一条消息开始之前不间断。例如不像[1/1/2013 00:00:00] (PID N) LOGMESS[1/1/2013 00:00:01] (PID M) LOGMESSAGE2\nAGE1
  2. 只要日志中出现的时间戳正确无误,就不需要跨进程严格排序日志消息。
  3. 更新

    我决定接受Tin Man的建议并写一个测试,你可以在这里找到: https://gist.github.com/4370423

    简短版本:Winfield是正确的,至少默认使用Logger,同时使用多个进程是安全的(对于上面给出的'safe'的定义)。

    关键因素似乎是如果给定文件路径(而不是已经打开的IO对象),Logger将以模式WRONLY|APPEND打开文件,并在其上设置sync=true。这两件事的组合(至少在Mac OS X上测试)似乎可以安全地从多个进程同时记录。如果要传入已打开的IO对象,请确保以相同的方式创建它。

1 个答案:

答案 0 :(得分:10)

是的,您可以按照您描述的方式安全地将交错日志数据写入单个日志文件。

但是,最好为每个进程记录一个单独的日志,或者使用像syslog这样的整合日志记录系统。以下是几个原因:

  • 日志轮换/管理:当您必须协调信号多个进程时,截断/滚动日志文件很困难
  • 即使您注入PID以消除歧义
  • ,交错数据也可能会造成混淆

我目前正在使用单个日志文件管理每个系统的一些Resque工作者,并希望我为每个工作者分隔了一个日志文件。调试问题和正确管理日志一直很困难。