2009-12-09 16 views
7

複数のスレッドからログを出力するためのシンプルなクラスを実装したいと思います。物事を記録したい各オブジェクトはostreamオブジェクトを受け取り、通常の演算子を使ってメッセージを書き込むことができるという考えがあります。望ましい動作は、ストリームがフラッシュされたときにメッセージがログに追加されることです。この方法では、メッセージは他のスレッドからのメッセージによって中断されません。私は、メッセージを格納するために一時的な文字列ストリームを使用することを避けたいと思います。それは、ほとんどのメッセージを少なくともtwolinersにするでしょう。私が見ているように、これを達成するための標準的な方法は自分自身のストリームバッファを実装することですが、これは非常に扱いにくく、エラーを起こしやすいようです。これを行う簡単な方法はありますか?そうでない場合、カスタムstreambufsに関する良い記事/ハウツ/ガイドを知っていますか?事前にスレッドセーフなログ

おかげで、

Space_C0wbo0y

UPDATE:

私が私自身の答えを追加動作しているようですので。

+0

良い解決策のようですね!おそらく自分の答えとしてそれを追加しますか? –

答えて

1

だから、私はBoost.IOstreamsで見ていたし、ここで私が作ってみたものです:(stream_buffer-templateを参照)、ストリームバッファを作成するために使用することができ

class TestSink : public boost::iostreams::sink { 
public: 
    std::streamsize write(const char * s, std::streamsize n) { 
     std::string message(s, n); 
      /* This would add a message to the log instead of cout. 
       The log implementation is threadsafe. */ 
     std::cout << message << std::endl; 
     return n; 
    } 
}; 

TestSink。すべてのスレッドはそれ自身のインスタンスTestSinkを受け取りますが、すべてTestSinksは同じログに書き込みます。次のようにTestSinkが使用されます。

TestSink sink; 
boost::iostreams::stream_buffer<TestSink> testbuf(sink, 50000); 
std::ostream out(&testbuf); 

for (int i = 0; i < 10000; i++) 
    out << "test" << i; 

out << std::endl; 

ここで重要なことは、(std::endlまたはstd::flush)ストリームがフラッシュされたときにTestSink.writeにのみ呼び出されること、である、またはstream_bufferインスタンスの内部バッファがいっぱいになったとき(デフォルトのバッファサイズは40000文字を保持できないので、私は50000に初期化します)。このプログラムでは、TestSink.writeが1回だけ呼び出されます(出力が長すぎてここに投稿できません)。このようにして、通常のフォーマットされたstream-IOを使って、一時変数を使わずにlogmessageを書くことができます。ストリームをフラッシュすると、メッセージがログに1つずつ記録されます。

私は考えていないさまざまな提案や問題がある場合は、別の日に質問を残しておきます。

5

log4cppをご覧ください。彼らはマルチスレッドをサポートしています。それはあなたの時間を節約するかもしれません。

+0

お返事ありがとうございます。しかし、私の職場環境の制約のため、新しい図書館を導入することはできません。また、ほとんどの既存のロギングライブラリは、私の目的のためにはあまりにも重量があります。 –

+0

より自由なライセンスを探す場合は、「Log4cxx by Apache」を参照してください。 http://logging.apache.org/log4cxx/index.html –

0

Re。あなた自身の反応。これをエラーロギングに使用していて、ストリームをフラッシュする前にプログラムがクラッシュすると、ロギングは少し役に立たないのですか?

+1

これは、どのロギング手法でも問題になると思います。 –

+0

外部ヘルプを持つETWのようなロギングシステムを除いて。 – VoidStar

1

あなたはlog4cppが重すぎてBoost.IOStreamsの代わりになると思いますか?ハァッ?

logogと考えてもよいでしょう。 POSIX、Win32、Win64ではスレッドセーフです。

+0

ブーストがすでに彼のライブラリのセットに入っているなら、それはあまり重いものではありません。それ以外の場合は、あなたに完全に同意します。 – John