如何让log4r输出消息同步?

时间:2015-09-08 08:12:33

标签: ruby logging log4r

我想知道为什么我在记录器调试输出之间引发了异常?

  DEBUG: asdjoasjd
  DEBUG: asdjoasjd 
  DEBUG: asdjoasjd
  **RuntimeError: something**
  DEBUG: continued debug message
  DEBUG: continued debug message
  DEBUG: continued debug message

虽然这个调试消息是在异常之前编写的吗?

$stdout.sync = true没有帮助。

我正在使用log4r

1 个答案:

答案 0 :(得分:1)

来自IO#sync文档:

  

当sync模式为true时,所有输出立即刷新到底层操作系统,并且不在内部缓冲。

这意味着Ruby不会在内部缓冲数据。不幸的是,这并不意味着任何OS缓冲,操作系统也可能缓冲数据。

另请注意,Log4r使用IO#flush来刷新数据,这些数据可以保证将数据刷新到底层操作系统,但不能再用它了。

  

将ios中的任何缓冲数据刷新到底层操作系统(请注意,这只是Ruby内部缓冲;操作系统也可以缓冲数据)。

你需要的是IO#fsync立即写入(刷新)所有缓冲数据。

  

立即将ios中的所有缓冲数据写入磁盘。请注意,fsync与使用IO#sync =不同。后者确保数据从Ruby的缓冲区中刷新,但不保证底层操作系统实际将其写入磁盘。

您可以继承Log4r::StdoutOutputter并提供自己的#write实施。

示例:

module Log4r
  class SyncedStdoutOutputter < StdoutOutputter
    def write(data)
      super(data)
      @out.fsync
    rescue NotImplementedError
      # fsync not supported by this OS
    end
  end
end

缓冲是好的,强烈建议出于性能原因,特别是在生产系统中。否则,您将面临消耗不必要资源的风险,例如对磁盘造成不必要的压力。

就个人而言,我认为Log4r已过时且有点不活跃。我尝试坚持使用原生Logger或至少ActiveSupport::Logger(基本上提供格式化程序)。看看logging等更现代的替代品。大多数记录仪都是可以互换的。