SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

オープンソースC++用クラスライブラリPOCO活用講座

5分で使えるLoggingフレームワーク - POCO::Foundation -

オープンソースC++用クラスライブラリPOCO活用講座(2)

Loggingフレームワークの構造

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

クラス構成
クラス構成

 大きく分けると、ログとして出力する文字列を格納するMessageクラスと、そのメッセージを書き込む処理を実装したChannelクラスの2つになっています。

 ただし、Channelクラスは、RefCountedObjectクラスとインターフェイスクラスであるConfigurableクラスを多重継承した抽象クラスです。実際にオブジェクトとして利用するのは、そのChannelクラスから派生したクラスで、Loggingフレームワークでのメインの操作クラスであるLoggerクラスと、具体的な書き込み先を実装した、ConsoleChannelクラスやFormattingChannelクラス等になります。

 RefCountedObjectクラスとは、「参照カウント」を実装したクラスです。参照カウントとは、そのオブジェクトがどれだけ参照されているか、つまり、そのオブジェクトを指すポインタがどれだけ存在するかをカウントしたものです。RefCountedObjectクラス自体のソースは単純なもので、自身をコピーするメンバ関数(duplicate)で参照カウントを1つ増加させ、破棄するメンバ関数(release)でカウントを1つ減らしています。減じたときにカウントが0になったら、実際に自身を破棄(delete this)しています。

 Configurableクラスは、いわゆるインターフェイスクラスで、クラス内のプロパティを操作するメンバ関数(setPropertygetProperty)を定義したクラスです。Loggingフレームワークの設定を変更する場合に、このクラスで定義されたメンバ関数を使用します。

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::debugLogger::traceの出力では、実際にはログ書き込みされないことになります。

ログ出力先を指定するChannel派生クラス

 ログの出力先として、Channelオブジェクトの指定が必ず必要です。Channelクラスは、単独で使用するものと、フィルタ的に他のChannelクラスと組み合わせて使うものの2種類あります。Loggerオブジェクトひとつにつき、Channelオブジェクトもひとつだけしか設定することができません。そのため、複数のChannelオブジェクトを使う場合は、オブジェクトを単方向のリスト構造でつなげる形になります。具体的なコード例は、後の「FormattingChannel」のところで説明します。

Channelクラス一覧
名称概要
ConsoleChannel (★)std::ostreamまたはstd::clogに出力。出力時の排他制御つき。
StreamChannelostreamに出力。
WindowsConsoleChannel(windowsのみ)メッセージをUTF-8と見なしてUTF-16コードに変換するConsoleChannel
FileChannel (★)ファイル出力。アーカイブ機能あり。
SimpleFileChannelFileChannelの簡易版。ローテート機能のみの実装。
NullChannel (★)NULLチャンネル、すべてのChannelオブジェクトの代わりになる。
EventLogChannel (★)(windowsのみ)イベントログサービスに出力。
OpcomChannelOpenVMS OPCOM service用。
SyslogChannelUnix syslog service用。
AsyncChannel非同期Channel。別スレッドにてキュー経由で出力。
FormattingChannel (★)フォーマッター付加用。
SplitterChannel (★)複数Channelオブジェクトに同時出力。

次のページ
Channel派生クラスの使い方

この記事は参考になりましたか?

オープンソースC++用クラスライブラリPOCO活用講座連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1901 2007/12/05 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー