是否有Ruby的异步日志记录库?

时间:2011-06-27 22:24:20

标签: ruby logging asynchronous concurrency

同步日志记录会因为可能阻塞而导致性能损失。是否有一个独立的Ruby库来执行异步日志记录(log4r似乎不是)?我可以修改标准库记录器以异步记录吗?我正在寻找类似log4j的AsyncAppender之类的东西 - 但最好是利用Ruby的代码块将尽可能多的工作转移到后台线程的实现。

4 个答案:

答案 0 :(得分:15)

我知道你不应该回答你自己的问题,但看起来红宝石一切都很简单:

require 'thread'
require 'singleton'
require 'delegate'
require 'monitor'

class Async
  include Singleton

  def initialize
    @queue = Queue.new
    Thread.new { loop { @queue.pop.call } }
  end

  def run(&blk)
    @queue.push blk
  end
end

class Work < Delegator
  include MonitorMixin

  def initialize(&work)
    super work; @work, @done, @lock = work, false, new_cond
  end

  def calc
    synchronize {
      @result, @done = @work.call, true; 
      @lock.signal
    }
  end

  def __getobj__
    synchronize { @lock.wait_while { !@done } }
    @result
  end
end

Module.class.class_exec {
  def async(*method_names) 
    method_names.each do |method_name|
      original_method = instance_method(method_name)
      define_method(method_name) do |*args,&blk|
        work = Work.new { original_method.bind(self).call(*args,&blk) }
        Async.instance.run { work.calc }
        return work
      end
    end
  end
}

对于我的日志示例:

require 'Logger'
class Logger
  async :debug
end
log = Logger.new STDOUT
log.debug "heloo"

由于返回值有效,您可以将它用于任何事情:

require "test/unit"
class ReturnValues < Test::Unit::TestCase
  def do_it
    5 + 7
  end
  async :do_it
  def test_simple
    assert_equal 10, do_it - 2
  end
end

答案 1 :(得分:2)

没有个人经验:

  

Swiftcore Analogger实现了快速异步记录系统   用于Ruby程序以及用于发送日志消息的客户端库   到模拟器过程。

     

Analogger将接受来自多个来源的日志,并且可以有多个日志   记录目的地。目前,记录到文件,STDOUT或   支持STDERR。未来的修订可能支持登录到   数据库目的地。

     

Analogger取决于EventMachine(http://rubyforge.org/projects/eventmachine)   为EM提供网络通信的框架   不用于客户端库。

答案 2 :(得分:1)

内置的Logger类已经是线程安全的

答案 3 :(得分:0)

Checkout Dunder https://github.com/fonsan/dunder

我在6个月前创建了这个宝石,只做这个以及更多