2011-06-27 8 views
11

同期ロギングは、ブロックされる可能性があるため、大きなパフォーマンス上のペナルティを招きます。非同期ロギングを行うスタンドアロンのRubyライブラリはありますか(log4rはそう思わない)?標準ライブラリロガーを非同期でログに変更できますか?私はlog4jのAsyncAppenderのようなものを探していますが、できるだけ多くの作業をバックグラウンドスレッドに移行するためにRubyのコードブロックを使用する実装が望ましいです。Ruby用の非同期ロギングライブラリはありますか?

+0

は 'ruby'通訳されている。これらの日はまだかなりときハムは神経質を行い6ヶ月前にこの宝石を作成し

https://github.com/fonsan/dunderそれはマルチスレッドコードになる?基本的なシングルスレッドネイティブのRubyコードの巨大なインタプリタロックはまだありますか?あなたがIOを非同期に強制するために、[eventmachine](http://rubyeventmachine.com/)のようなフレームワークを既に使用していない限り、実際にはログを非同期にすることによるメリットはありません。 – sarnold

+0

私は通常JRubyを使用していますので、本当のJavaスレッドを持っています(私は思う)。 –

+0

ooh;)これはJRubyの使用を検討する魅力的な理由です。ありがとう。 – sarnold

答えて

15

あなたはこれを何かのために使うことができます:

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 
+0

優れています。 Rubyの表現力は常に私を驚かせる。あなたはJRubyを使って言いましたので、本当のスレッドを持っている可能性がありますが、多くの動的なルビーの魔法も使用していますので、JRubyはすべての動的なトリックにどれくらいうまく対処していますか? JRubyとMRIのベンチマークを並べて見るのはすばらしいことです。 – davidk01

+0

ニースコード!ファイバー/イベントマシンを使うほうが良いかもしれません。スレッドは仕事をするでしょうが、MRI(そしてJRubyの将来)ではより重く、管理と同期が必要です。私はすでにあなたが望むものに近いかもしれないイベントマシンのファイルストリーマーがあると思います:http://stackoverflow.com/questions/2749503/what-is-the-best-way-to-read-files-in-an -eventmachine-based-app –

2

ものではありません個人的な経験:

Swiftcore Analoggerはに をログに記録するメッセージを送信するための高速非同期Rubyプログラムのためのロギングシステム だけでなく、クライアントライブラリを実装アナロジープロセス。

Analoggerは、複数のソースからのログを受け入れ、複数のログ宛先を持つことができます( )。現在、ファイル、STDOUT、または STDERRへのロギングがサポートされています。将来のリビジョンでは、 データベース宛先へのロギングもサポートされる可能性があります。

AnaloggerはEMが クライアントライブラリを使用していないが、ネットワーク通信のためのフレームワークを提供するために、EventMachine(http://rubyforge.org/projects/eventmachine) に依存します。

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 { [email protected] } } 
    @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" 

を、私はあなたが本当にあなた自身の質問に答えるべきではありませんが、すべてがRubyで使いやすいようです知っ

+0

これは別のプロセスで非同期ロギングを完全に行うと思われます - 私はプロセス内のロギングを(別のスレッドで)好むでしょう –

1

すでに

+0

ログメッセージをディスクに別のスレッドで書きたいので、IOブロックがメインスレッドの処理速度を落とさないようにします。 –

0

アウトDunderスレッドセーフされたLoggerクラスに組み込まれて、私はただの本以上が

関連する問題