ここでは、log4cpp::Categoryクラスのlogメソッド(あるいは優先度ごとに用意されたメソッド、すなわち、debug、info、notice、warn、error、crit、alert、emerg、fatal)を呼んだときにどのような流れで実際にログ出力が行われるかを説明します。
図1はログ出力時の処理の流れをUML2.0のシーケンス図で表記したものです。
細かい部分は省いています。実際には、Category::log()が呼ばれると、
という感じです。さらに図1の1.3.1~1.3.3の部分(Appender::doAppend()の内部)は実際にはAppenderSkelton(Appenderのサブクラス)での処理なのですが、図1ではさすがにここまで記述していません。
以下に、ポイントとなる部分を説明します。
APIドキュメントを見れば分かると思いますが、ログ出力するデータを保持するクラスです。
これの存在理由ですが、たとえば、ログ出力時の現在時刻というのは、ログを出力するたびに取得していたら、Categoryが複数のAppenderを持っていたときに、最初の出力(最初のAppender)と最後出力(最後のAppender)で時刻が変わってしまいますが、まあ、そういう風にならないようにという理由が1つあると思います。あとは、Appenderを継承して自作のAppenderを作成するときやフォーマットを考えるときに、出力するのって何?とならないように定義しているという意味もあると思います。
遅くなります。
log4cppのコアの部分ではログ出力を別スレッドで行うということはしていません。ですので、Appenderが多いと、Category::log()が帰ってくるまでにかかる時間が長くなります。
はっきり言うが、スレッドセーフでないとログ出力ライブラリとして使えない。シーケンス図を見るとcriticalと記載があり、排他をかけている。
・・・と、言うことは、スレッドセーフなのだろうか・・・?
しかし、Log for C++ の本家サイトのFAQの「3.2. Is log4cpp thread-safe?」を見ると、なんと質問に対する答えが書かれていないです。
※注意:ここから先、間違っていたら申し訳ないです。
log4cppのソースを読んだ限りでは、排他をかけているので、もちろん、スレッドセーフなのですが、条件があります。