0

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

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

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

$stdout.sync = true没有帮助。

我正在使用 log4r

4

1 回答 1

1

IO#sync文档:

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

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

另请注意,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。大多数记录器是可互换的。

于 2015-09-08T23:09:09.187 回答