Synchronous logging incurs a large performance penalty as it may block. Is there a standalone Ruby library that does asynchronous logging (log4r doesn't seem to)? Can I modify the standard library logger to log asynchronously? I'm looking for something like log4j's AsyncAppender - but preferably an implementation that makes use of Ruby's code blocks to shift as much work to the background thread as possible.
I know you shouldn't really answer your own question, but it seems everything is easy in ruby:
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
}
And for my logging example:
require 'Logger'
class Logger
async :debug
end
log = Logger.new STDOUT
log.debug "heloo"
As return values work, you can use this for just about anything:
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
No personal experience with that:
The Swiftcore Analogger implements a fast asynchronous logging system for Ruby programs as well as client library for sending logging messages to the Analogger process.
Analogger will accept logs from multiple sources and can have multiple logging destinations. Currently, logging to a file, to STDOUT, or to STDERR is supported. A future revision may support logging to a database destination, as well.
Analogger depends on EventMachine (http://rubyforge.org/projects/eventmachine) to provide the framework for the network communications, though EM is not used for the client library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With