最快的 Ruby 记录器实现是什么?

发布于 2024-08-03 19:35:58 字数 1688 浏览 3 评论 0原文

我想找到 Ruby 提供的最快的记录器。我的直觉告诉我 syslog 将在这场竞赛中获胜。但我的直觉似乎是错误的。事实证明,Syslog 是我测试过的三个记录器中最慢的。我使用的是 MacBook Pro、OSX 10.6 (Snow Leopard)、Intel Core2 Duo、4GB RAM 和由 MacPorts 构建的 Ruby 1.8.7。我做错了什么吗?或者 Ruby 的 syslog 实现就这么慢?如果您的结果与我的不同,请随时发布。也欢迎您将您最喜欢的 Ruby 记录器添加到基准测试中。我的目标是找到最快的记录器。我只对纯粹的性能(吞吐量)感兴趣。多目标日志记录等功能不是这里关注的问题。

# loggers_bench.rb

require 'rbench'
require 'activesupport'
require 'syslog'
require 'logger'

buffered = ActiveSupport::BufferedLogger.new('buffered.log')
logger   = Logger.new('logger.log')
syslog   = Syslog.open('rb_syslog')

TIMES = 10_000

RBench.run(TIMES) do
  column :syslog,    :title => 'Syslog'
  column :logger,    :title => 'Logger'
  column :buffered,  :title => 'ActiveSuppoort::BufferedLogger'


  report '#info' do
    syslog {
      300.times do |i|
        syslog.info "hello #{i}"
      end
    }

    logger {
      300.times do |i|
        logger.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
    }
    buffered {
      300.times do |i|
        buffered.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
    }

  end
end

# > RUBYOPT=rubygems ruby loggers_bench.rb 
#                Syslog |  Logger | ActiveSuppoort::BufferedLogger|
# -----------------------------------------------------------------
# #info         158.316 | 117.882 |                        98.707 |

请注意,我只使用了更简单的形式:“hello #{i}”作为 Syslog(理论上这应该更快,但事实并非如此)。另外,我的 Mac 的默认 syslogd 似乎有有限的消息配额(500/秒)。系统日志中不时生成以下消息:

*** process 1962 exceeded 500 log message per second limit  -  remaining messages this second discarded ***

I want to find the fastest logger Ruby has to offer. My intuition tells me that syslog would win in this race. But my intuition seems to be wrong. Syslog turns out to be the slowest out of the three loggers I've tested. I'm using my MacBook Pro, OSX 10.6 (Snow Leopard), Intel Core2 Duo, 4GB of RAM and Ruby 1.8.7 built from MacPorts. Am I doing something wrong? Or Ruby's syslog implementation is just that slow? Feel free to post your results if they're different from mine. You are also welcome to add your favorite Ruby logger to the benchmark. My goal is to find the fastest logger available. I'm only interested in pure performance (throughput). Features like multi-target logging is not the concern here.

# loggers_bench.rb

require 'rbench'
require 'activesupport'
require 'syslog'
require 'logger'

buffered = ActiveSupport::BufferedLogger.new('buffered.log')
logger   = Logger.new('logger.log')
syslog   = Syslog.open('rb_syslog')

TIMES = 10_000

RBench.run(TIMES) do
  column :syslog,    :title => 'Syslog'
  column :logger,    :title => 'Logger'
  column :buffered,  :title => 'ActiveSuppoort::BufferedLogger'


  report '#info' do
    syslog {
      300.times do |i|
        syslog.info "hello #{i}"
      end
    }

    logger {
      300.times do |i|
        logger.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
    }
    buffered {
      300.times do |i|
        buffered.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
    }

  end
end

# > RUBYOPT=rubygems ruby loggers_bench.rb 
#                Syslog |  Logger | ActiveSuppoort::BufferedLogger|
# -----------------------------------------------------------------
# #info         158.316 | 117.882 |                        98.707 |

Note that I've only used the simpler form: "hello #{i}" for Syslog (in theory this should be even faster, but it's not). Also my Mac's default syslogd seems to have a limited messages quota (500/sec). The following message is generated from time to time in the syslog:

*** process 1962 exceeded 500 log message per second limit  -  remaining messages this second discarded ***

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北凤男飞 2024-08-10 19:35:58

好的,我更新了脚本以包含 log4r,这是我的偏好,因为它支持很多不同的功能。 (滚动日志,耶!)

我还在缓冲记录器上添加了 .flush,并减少了测试时间,因此不会永远花费时间。 log4r 仅比缓冲记录器慢一点。那将是我的选择。

# loggers_bench.rb

require 'rbench'

require 'active_support'
require 'stringio'
buffered = ActiveSupport::BufferedLogger.new('buffered.log')
require 'logger'
logger   = Logger.new('logger.log')
require 'syslog'
syslog   = Syslog.open('rb_syslog')
require 'log4r'
log4r = Log4r::Logger.new 'mylog'
log4r.outputters = Log4r::FileOutputter.new('log', :filename => 'log4r.log')

TIMES = 5_000

RBench.run(TIMES) do
  column :syslog,    :title => 'Syslog'
  column :logger,    :title => 'Logger'
  column :buffered,  :title => 'ActiveSuppoort::BufferedLogger'
  column :log4r,     :title => 'log4r'


  report '#info' do
    syslog {
      10.times do |i|
        syslog.info "hello #{i}"
      end
    }

    logger {
      10.times do |i|
        logger.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
    }

    buffered {
      10.times do |i|
        buffered.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
      buffered.flush
    }

    log4r {
      10.times do |i|
        log4r.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
    }
  end
end
#                Syslog |  Logger | ActiveSuppoort::BufferedLogger |   log4r |
# ----------------------------------------------------------------------------
# #info           2.377 |   2.040 |                          1.425 |   1.532 |

Ok, I updated the script to include log4r, which is my preference because it supports so many different features. (rolling logs, yay!)

I also included a .flush on the buffered logger, and lessened the test times so it doesn't take forever. log4r was only slightly slower than the buffered logger. That'd be my choice.

# loggers_bench.rb

require 'rbench'

require 'active_support'
require 'stringio'
buffered = ActiveSupport::BufferedLogger.new('buffered.log')
require 'logger'
logger   = Logger.new('logger.log')
require 'syslog'
syslog   = Syslog.open('rb_syslog')
require 'log4r'
log4r = Log4r::Logger.new 'mylog'
log4r.outputters = Log4r::FileOutputter.new('log', :filename => 'log4r.log')

TIMES = 5_000

RBench.run(TIMES) do
  column :syslog,    :title => 'Syslog'
  column :logger,    :title => 'Logger'
  column :buffered,  :title => 'ActiveSuppoort::BufferedLogger'
  column :log4r,     :title => 'log4r'


  report '#info' do
    syslog {
      10.times do |i|
        syslog.info "hello #{i}"
      end
    }

    logger {
      10.times do |i|
        logger.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
    }

    buffered {
      10.times do |i|
        buffered.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
      buffered.flush
    }

    log4r {
      10.times do |i|
        log4r.info "#{Time.now} logging_logger[Process.pid]:  INFO  logging_logger : hello #{i}"
      end
    }
  end
end
#                Syslog |  Logger | ActiveSuppoort::BufferedLogger |   log4r |
# ----------------------------------------------------------------------------
# #info           2.377 |   2.040 |                          1.425 |   1.532 |
没有伤那来痛 2024-08-10 19:35:58

我猜测 BufferedLogger 名称的第一部分解释了它的速度,与其他两个部分相比,我希望它们在收到消息后立即写入。

权衡是缓冲对象吞吐量的提高和 IO 负载的减少,以及存储中未刷新消息的大规模崩溃可能导致的日志信息丢失。

我想知道,为了在不损失所有消息安全性的情况下增加吞吐量并以增加复杂性为代价,是否可以将两种形式结合起来:使用缓冲记录器来获取有用但不需要 100.0000% 完整的信息(即小信息)偶尔的丢失不会造成痛苦),以及您为出于法律或诊断目的而必须拥有的消息选择的非缓冲消息。

如果与必备消息相比,必备消息的数量相对较低(而且应该如此,或者这种方法可能不必要地复杂),那么您使用哪种非缓冲记录器并不重要。

I'm guessing that the first part of BufferedLogger's name explains its speed, compared with the other two, which I expect to be writing messages as soon as they're received.

The tradeoff would be the improved throughput of the buffered object with its reduced IO load against the possible loss of log information resulting from a wholesale crash with unflushed messages in store.

I wonder if, to increase throughput without the loss of all message security and at the cost of increased complexity, it might be possible to combine the two forms: use a buffered logger for information that's useful but need not be 100.0000% complete (i.e. small occasional losses don't cause pain) and a non-buffered one of your choice for messages that you simply must have, for legal or diagnostic purposes, say.

If the volume of must-have messages is relatively low compared to the nice-to-haves (and it should be or this approach is probably needlessly complex) then which non-buffered logger you use won't matter much.

用心笑 2024-08-10 19:35:58

尝试使用 syslog-ng,结果是:

TIMES: 50
用户系统总真实数
系统日志 0.000000 0.000000 0.000000 ( 0.006187)
记录仪 0.000000 0.010000 0.010000 ( 0.003698)
BUFFERED 0.000000 0.000000 0.000000 ( 0.003069)

bufferred 记录器似乎更好。

tried with syslog-ng and the results are:

TIMES: 50
user system total real
SYSLOG 0.000000 0.000000 0.000000 ( 0.006187)
LOGGER 0.000000 0.010000 0.010000 ( 0.003698)
BUFFERED 0.000000 0.000000 0.000000 ( 0.003069)

bufferred logger seems to better.

稚然 2024-08-10 19:35:58

您还应该查看日志记录 (http://github.com/TwP/logging) 框架。有一个基准(https://github.com/TwP/logging/blob/master/test/benchmark.rb)文件,您可以查看该文件来与 log4r 和核心 ruby​​ 记录器进行一些比较。

You should also look at the logging (http://github.com/TwP/logging) framework. There is a benchmark (https://github.com/TwP/logging/blob/master/test/benchmark.rb) file that you can look at to do some comparisons with log4r and the core ruby logger.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文