最快的 Ruby 记录器实现是啥?
Posted
技术标签:
【中文标题】最快的 Ruby 记录器实现是啥?【英文标题】:What is the fastest Ruby logger implementation?最快的 Ruby 记录器实现是什么? 【发布时间】:2009-09-09 07:38:22 【问题描述】:我想找到 Ruby 提供的最快的记录器。我的直觉告诉我,syslog 会在这场比赛中获胜。但我的直觉似乎是错误的。 Syslog 是我测试过的三个记录器中最慢的。我正在使用我的 MacBook Pro、OSX 10.6 (Snow Leopard)、Intel Core2 Duo、4GB 内存和由 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 |
请注意,我只对 Syslog 使用了更简单的形式:“hello #i”(理论上这应该更快,但事实并非如此)。此外,我的 Mac 的默认 syslogd 似乎具有有限的消息配额(500/秒)。系统日志中不时生成以下消息:
*** process 1962 exceeded 500 log message per second limit - remaining messages this second discarded ***
【问题讨论】:
【参考方案1】:好的,我更新了脚本以包含 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 |
【讨论】:
【参考方案2】:我猜BufferedLogger
名称的第一部分解释了它的速度,与其他两个相比,我希望在收到消息后立即写入。
折衷方案是提高缓冲对象的吞吐量并减少 IO 负载,以防止由于存储中未刷新消息的大规模崩溃而可能导致日志信息丢失。
我想知道,为了在不损失所有消息安全性并以增加复杂性为代价的情况下增加吞吐量,是否可以将两种形式结合起来:使用缓冲记录器来获取有用但不需要 100.0000% 完整的信息(即偶尔的小损失不会引起痛苦)和一个非缓冲的消息,您选择的消息是您只是必须拥有的消息,例如出于法律或诊断目的。
如果必备消息的数量与必备消息相比相对较低(应该是这样,或者这种方法可能不必要地复杂),那么您使用哪个非缓冲记录器就无关紧要了。
【讨论】:
【参考方案3】:用 syslog-ng 试过,结果是:
次数:50 用户系统总实数 系统日志 0.000000 0.000000 0.000000 ( 0.006187) 记录仪 0.000000 0.010000 0.010000 ( 0.003698) 缓冲 0.000000 0.000000 0.000000 ( 0.003069)
缓冲记录器似乎更好。
【讨论】:
【参考方案4】:您还应该查看日志记录 (http://github.com/TwP/logging) 框架。有一个基准 (https://github.com/TwP/logging/blob/master/test/benchmark.rb) 文件,您可以查看它来与 log4r 和核心 ruby 记录器进行一些比较。
【讨论】:
以上是关于最快的 Ruby 记录器实现是啥?的主要内容,如果未能解决你的问题,请参考以下文章