14

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

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

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

这就是我所说的“安全”的意思:

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

更新

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

简短版本:Winfield 是正确的,至少默认使用Logger它可以安全地同时从多个进程中使用(对于上面给出的“安全”的定义)。

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

4

1 回答 1

10

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

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

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

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

于 2012-12-20T19:00:22.183 回答