【问题标题】:How to make log4r output messages syncronous?如何使 log4r 输出消息同步?
【发布时间】:2015-09-08 08:12:33
【问题描述】:

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

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

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

$stdout.sync = true 没有帮助。

我正在使用 log4r

【问题讨论】:

    标签: ruby logging log4r


    【解决方案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。大多数记录器都是可互换的。

    【讨论】:

      猜你喜欢
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 2019-06-25
      • 2021-08-17
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多