Loggingフレームワークの構造
Loggingパッケージは、単なるクラスの寄せ集めというわけではなく、Loggingフレームワークとして設計されています。そのため、使用する際には、全体の構造を理解しておくのが望ましいでしょう。基本となるクラスの構成は次の図のようになります。

大きく分けると、ログとして出力する文字列を格納するMessageクラスと、そのメッセージを書き込む処理を実装したChannelクラスの2つになっています。
ただし、Channelクラスは、RefCountedObjectクラスとインターフェイスクラスであるConfigurableクラスを多重継承した抽象クラスです。実際にオブジェクトとして利用するのは、そのChannelクラスから派生したクラスで、Loggingフレームワークでのメインの操作クラスであるLoggerクラスと、具体的な書き込み先を実装した、ConsoleChannelクラスやFormattingChannelクラス等になります。
RefCountedObjectクラスとは、「参照カウント」を実装したクラスです。参照カウントとは、そのオブジェクトがどれだけ参照されているか、つまり、そのオブジェクトを指すポインタがどれだけ存在するかをカウントしたものです。RefCountedObjectクラス自体のソースは単純なもので、自身をコピーするメンバ関数(duplicate)で参照カウントを1つ増加させ、破棄するメンバ関数(release)でカウントを1つ減らしています。減じたときにカウントが0になったら、実際に自身を破棄(delete this)しています。
Configurableクラスは、いわゆるインターフェイスクラスで、クラス内のプロパティを操作するメンバ関数(setPropertyとgetProperty)を定義したクラスです。Loggingフレームワークの設定を変更する場合に、このクラスで定義されたメンバ関数を使用します。
Loggingフレームワークの基本
ここで実際のコードをお見せしましょう。言葉でクドクド説明するより、わかりやすいと思います。最小のサンプルコードは次のようになります。
#include "Poco/Logger.h" #include "Poco/ConsoleChannel.h" #include "Poco/Message.h" int main(int argc, char** argv) { Poco::Logger& consoleLogger = Poco::Logger::create( "ConsoleLogger", new Poco::ConsoleChannel, Poco::Message::PRIO_INFORMATION ); consoleLogger.error( "エラーが発生しました" ); }
まず、Loggerクラスのオブジェクトを生成しています。そして、そのLoggerオブジェクトに対してログメッセージを書き込んでいます。
Loggerクラス
Loggerクラスは、フレームワークのメインクラスで、実体として生成するLoggerオブジェクトの抽象的なクラスにもなっています。Channelクラスから派生したクラスですが、他のChannel派生クラスとは違い、特別なクラスになっています。
生成と開放は、フレームワーク内部で管理されています。インスタンス生成は、static関数であるLogger::createを用い、Loggerオブジェクトをいくつでも生成可能です。また、解放処理を記述する必要はありません。Channelクラスも、基底クラスがRefCountedObjectになっていますから、解放処理を気にする必要はありません。
Logger::createの最初の引数は、生成するLoggerオブジェクトの名前です。名前は任意につけてかまいません。ただ、すでに生成済みの名前を指定すると、例外(Poco::ExistsException)が発生します。
2番目の引数は、書き込み先のクラスであるChannelクラスのオブジェクトをセットします。3番目は、ログ・メッセージのレベルを指定します。メッセージのレベルは優先度の高いほうから、
- PRIO_FATAL
- PRIO_CRITICAL
- PRIO_ERROR
- PRIO_WARNING
- PRIO_NOTICE
- PRIO_INFORMATION
- PRIO_DEBUG
- PRIO_TRACE
となっています。書き込み対象になるメッセージは、設定されたレベル以上の優先度をもつメッセージとなります。レベルに応じたログ書き込み関数は、次のようになっています。
void Logger::fatal(const std::string& msg); void Logger::critical(const std::string& msg); void Logger::error(const std::string& msg); void Logger::warning(const std::string& msg); void Logger::notice(const std::string& msg); void Logger::information(const std::string& msg); void Logger::debug(const std::string& msg); void Logger::trace(const std::string& msg);
サンプルコードの場合では、PRIO_INFORMATIONを指定していますので、それより優先度の低いLogger::debug、Logger::traceの出力では、実際にはログ書き込みされないことになります。
ログ出力先を指定するChannel派生クラス
ログの出力先として、Channelオブジェクトの指定が必ず必要です。Channelクラスは、単独で使用するものと、フィルタ的に他のChannelクラスと組み合わせて使うものの2種類あります。Loggerオブジェクトひとつにつき、Channelオブジェクトもひとつだけしか設定することができません。そのため、複数のChannelオブジェクトを使う場合は、オブジェクトを単方向のリスト構造でつなげる形になります。具体的なコード例は、後の「FormattingChannel」のところで説明します。
| 名称 | 概要 |
| ConsoleChannel (★) | std::ostreamまたはstd::clogに出力。出力時の排他制御つき。 |
| StreamChannel | ostreamに出力。 |
| WindowsConsoleChannel | (windowsのみ)メッセージをUTF-8と見なしてUTF-16コードに変換するConsoleChannel。 |
| FileChannel (★) | ファイル出力。アーカイブ機能あり。 |
| SimpleFileChannel | FileChannelの簡易版。ローテート機能のみの実装。 |
| NullChannel (★) | NULLチャンネル、すべてのChannelオブジェクトの代わりになる。 |
| EventLogChannel (★) | (windowsのみ)イベントログサービスに出力。 |
| OpcomChannel | OpenVMS OPCOM service用。 |
| SyslogChannel | Unix syslog service用。 |
| AsyncChannel | 非同期Channel。別スレッドにてキュー経由で出力。 |
| FormattingChannel (★) | フォーマッター付加用。 |
| SplitterChannel (★) | 複数Channelオブジェクトに同時出力。 |
