如何使 log4r 输出消息同步?

How to make log4r output messages syncronous?

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

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

虽然此调试消息是在异常发生之前编写的?

$stdout.sync = true 没有帮助。

我正在使用 log4r

来自 IO#sync 文档:

When sync mode is true, all output is immediately flushed to the underlying operating system and is not buffered internally.

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

另请注意,Log4r 使用 IO#flush 刷新数据,这保证了数据将被刷新到底层 OS 但仅此而已。

Flushes any buffered data within ios to the underlying operating system (note that this is Ruby internal buffering only; the OS may buffer the data as well).

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

Immediately writes all buffered data in ios to disk. Note that fsync differs from using IO#sync=. The latter ensures that data is flushed from Ruby’s buffers, but does not guarantee that the underlying operating system actually writes it to disk.

您可以子类化 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。大多数记录器是可以互换的。