[ C++で開発 ] [ ロギングライブラリの選択 ]

ロギングライブラリ Pantheios を使う

性能、頑健性、透過性を設計主眼としたオープンソースC/C++ロギングAPIライブラリ Pantheios を使ってみます。

ビルド

Pantheios はBSD-styleライセンスのオープンソースライブラリのため、ソースファイル一式として入手し、ライブラリを使用する開発環境(コンパイラ)でビルドし、ライブラリとして利用できるよう構築します。

ソースファイル一式の入手

Pantheiosは、内部でSTLsoftと呼ばれるライブラリを利用しているので、STLsoftのソースファイル一式とPantheiosのソースファイル一式を入手します。

STLsoftは、Matthew Wilsonが開発しているSTLを補うテンプレートライブラリ、OS固有のAPIのラッパーを提供するライブラリです。ヘッダーのみで利用できます。BSDライセンス。

Pantheiosの入手

Pantheios公式ページから、This Website節の箇条書きにある[Downloads]のリンクを辿ります。
pantheios distribution の箇条書き項の右にある[SourceForge]のリンクを辿ります。
[Pantheios (C and Cxx)]のリンクを辿り、バージョン一覧の最新のものをクリックします。4つほどファイルがリストされるので、次のような名前のファイルをダウンロードします。

STFsoftの入手

Pantheios公式ページから、This Website節の箇条書きにある[Downloads]のリンクを辿ります。
STLsoft distribution の箇条書き項の右にある[STLSoft website]のリンクを辿ります。
STLSoftのWebサイトのメニューから[Downloads]をクリックすると、SourceForgeのページが開き、自動で最新版のファイルがダウンロードされます。

Windows 7上のVisual Studio 2010でビルド

Visual C++で作成するC++プログラムからロギングライブラリを使用するため、Visual C++用のライブラリをビルドします。

参考記事

ライブラリを置く場所の方針

VC++プログラミングで利用する各種ライブラリを、開発PC上のどこに置くか決めます。特に定番という場所はないようです。そこで、次のように置くことにします(今考えた!)。

C:\Program Files
   +--- CxxLibs
           +--- <ライブラリ名>
                   +--- include
                   |       +--- *.h  <- ヘッダーファイル(サブディレクトリ可)
                   |    
                   +--- lib
                   |       +--- amd64
                   |       |      +--- *.lib   <- 64bit版インポートライブラリ
                   |       |
                   |       +--- *.lib   <- 32bit版インポートライブラリ
                   |
                   +--- bin
                           +--- amd64
                           |       +--- *.dll   <- 64bit版ダイナミックリンクライブラリ
                           |
                           +--- *.dll   <- 32bit版ダイナミックリンクライブラリ

できればインストーラを作ってこのディレクトリにインストールするようにしたいところです。

STLsoftの展開

STLsoftはヘッダーファイルだけで利用できるライブラリなので、ビルドせずにライブラリ置き場にコピーします。

ダウンロードしたファイルstlsoft-1.9.116-hdrs.zipを解凍・展開してできたstlsoft-1.9.116フォルダを、C:\Program Files\CxxLibsの下にコピーします。

C:\Program Files
   +--- CxxLibs
           +--- stlsoft-1.9.116
                   +--- include
                           +--- acestl
                           +--- atlstl
                           :
                           +--- stlsoft
                           :
                           +--- wtlstl

環境変数STLSOFTを定義します。次のPantheiosのビルドで参照されます。

環境変数の定義は、そのPCにログインするユーザー全員に反映されるシステム環境変数と、特定ユーザーに反映されるユーザー環境変数、特定のコマンドプロンプト上でのみ反映される設定(setコマンドで指定)があります。今回は、ユーザー環境変数として定義することにします。

まず、[スタート]>[コントロールパネル]>[システムとセキュリティ]>[システム]>[システムの詳細設定]で、「システムのプロパティ」ダイアログが表示されます。[詳細設定]タブを選び、[環境変数]ボタンを押します。

ユーザー環境変数欄の[新規]ボタンを押し、「新しいユーザー変数」ダイアログが表示されるので、次を入力します。

Pantheiosの展開

Pantheiosはビルドする必要があるので、自由にファイルの読み書きができるユーザー・ディレクトリ下(ドキュメント下など)に展開します。

C:\Users\<ユーザー名>\Documents\work\pantheios-1.0.1-beta214
<ユーザー名>の箇所はログインして作業しているアカウント名に置き換えてください。

Visual Studioのコマンドラインツールを起動します。

[スタート]>[すべてのプログラム]>[Microsoft Visual Studio 2010]>[Visual Studio Tools]>[Visual Studio コマンド プロンプト(2010)]を実行します。

このコマンドプロンプト上でPantheiosを展開したディレクトリの中にあるbuild\vc10に移動します。

C:\> cd C:\Users\<ユーザー名>\Documents\work\pantheios-1.0.1-beta214\build\vc10

C:\Users\<ユーザー名>\Documents\work\pantheios-1.0.1-beta214\build\vc10>

nmake test を実行します。ビルドが完了したらテストを実行します。

C:\Users\<ユーザー名>\Documents\work\pantheios-1.0.1-beta214\build\vc10> nmake test
  :

おっと早々にコンパイルエラーが発生してしまいました。

        cl    -nologo -c -W4 -wd4800 -wd4996 -WX    -EHsc -GR -MTd -DUNICODE -D_
UNICODE -D_DEBUG -Zi -Fd.\test.unit.util.onbailout.ws.mt.debug.pdb   -DWIN32
 -I..\..\include -I"C:\Program Files\CxxLibs\stlsoft-1.9.116\include"   -Fo.\tes
t.unit.util.onbailout.ws.mt.debug.obj ..\..\test\unit\test.unit.util.onbailout\t
est.unit.util.onbailout.cpp
test.unit.util.onbailout.cpp
..\..\test\unit\test.unit.util.onbailout\test.unit.util.onbailout.cpp(181) : err
or C2664: 'xtests::c::xtests_startRunner' : 1 番目の引数を 'const pan_char_t [25
]' から 'const char *' に変換できません。(新しい機能 ; ヘルプを参照)
        指示された型は関連がありません。変換には reinterpret_cast、C スタイル キ
ャストまたは関数スタイルのキャストが必要です。
NMAKE : fatal error U1077: '"c:\Program Files (x86)\Microsoft Visual Studio 10.0
\VC\BIN\cl.EXE"' : リターン コード '0x2'
Stop.

テストコードで発生しているので、いったんテストはあきらめ、ビルドのみを行う nmake build.libs を実行します。

C:\Users\<ユーザー名>\Documents\work\pantheios-1.0.1-beta214\build\vc10> nmake build.libs
  :

ビルド結果はpantheios-1.0.1-beta214\lib ディレクトリにライブラリファイルとして生成されます。かなり数が多いのですが、おおよその内容を見てみます。

まず、ライブラリ1つ毎に、DLLデバッグ用、DLLリリース用、スタティックリンクデバッグ用、スタティックリンクリリース用と4つ、それからワイド文字セット(ユニコード)対応版の同じく4つと計8個のライブラリファイルが生成されています。以下に、pantheiosのcoreライブラリとして生成されるファイルを列挙します。

pantheios.1.core.vc10.dll.debug.lib
pantheios.1.core.vc10.dll.lib
pantheios.1.core.vc10.mt.debug.lib
pantheios.1.core.vc10.mt.lib
pantheios.1.core.vc10.widestring.dll.debug.lib
pantheios.1.core.vc10.widestring.dll.lib
pantheios.1.core.vc10.widestring.mt.debug.lib
pantheios.1.core.vc10.widestring.mt.lib

widestringは、Visual C++でユニコード文字セットを使用する設定でビルドしたときに使われるものです。

次に、ライブラリは次の種類となります(各ライブラリ毎に上述の8つのファイルがあります)。

pantheios.1.appl
pantheios.1.be.COMErrorObject
pantheios.1.be.fail
pantheios.1.be.file
pantheios.1.be.fprintf
pantheios.1.be.lrsplit
pantheios.1.be.N
pantheios.1.be.null
pantheios.1.be.speech
pantheios.1.be.test
pantheios.1.be.WindowsConsole
pantheios.1.be.WindowsDebugger
pantheios.1.be.WindowsEventLog
pantheios.1.be.WindowsMessageBox
pantheios.1.be.WindowsSyslog
pantheios.1.bec.COMErrorObject
pantheios.1.bec.COMErrorObject.WithCallback
pantheios.1.bec.fail
pantheios.1.bec.file
pantheios.1.bec.file.WithCallback
pantheios.1.bec.fprintf
pantheios.1.bec.fprintf.WithCallback
pantheios.1.bec.null
pantheios.1.bec.speech
pantheios.1.bec.speech.WithCallback
pantheios.1.bec.test
pantheios.1.bec.WindowsConsole
pantheios.1.bec.WindowsConsole.WithCallback
pantheios.1.bec.WindowsDebugger
pantheios.1.bec.WindowsDebugger.WithCallback
pantheios.1.bec.WindowsEventLog
pantheios.1.bec.WindowsMessageBox
pantheios.1.bec.WindowsSyslog
pantheios.1.bec.WindowsSyslog.WithCallback
pantheios.1.bel.COMErrorObject
pantheios.1.bel.fail
pantheios.1.bel.file
pantheios.1.bel.fprintf
pantheios.1.bel.null
pantheios.1.bel.speech
pantheios.1.bel.test
pantheios.1.bel.WindowsConsole
pantheios.1.bel.WindowsDebugger
pantheios.1.bel.WindowsEventLog
pantheios.1.bel.WindowsMessageBox
pantheios.1.bel.WindowsSyslog
pantheios.1.ber.COMErrorObject
pantheios.1.ber.fail
pantheios.1.ber.file
pantheios.1.ber.fprintf
pantheios.1.ber.null
pantheios.1.ber.speech
pantheios.1.ber.test
pantheios.1.ber.WindowsConsole
pantheios.1.ber.WindowsDebugger
pantheios.1.ber.WindowsEventLog
pantheios.1.ber.WindowsMessageBox
pantheios.1.ber.WindowsSyslog
pantheios.1.core
pantheios.1.fe.all
pantheios.1.fe.all.WithCallback
pantheios.1.fe.fail
pantheios.1.fe.N
pantheios.1.fe.N.WithCallback
pantheios.1.fe.null
pantheios.1.fe.null.WithCallback
pantheios.1.fe.simple
pantheios.1.fe.simple.WithCallback
pantheios.1.fe.WindowsRegistry
pantheios.1.fe.WindowsRegistry.WithCallback
pantheios.1.util

通常、アプリケーションにリンクするのは、core、be/becの中から適するものを1つ、feの中から適するものを1つ、utilとなります。リンクするライブラリによって挙動(ログの出力先など)が決まります。

includeディレクトリとlibディレクトリを、C:\Program Files\CxxLibsの下にpantheios-1.0.1-beta214ディレクトリを作成し、その下にコピーします。

C:\Program Files
   +--- CxxLibs
           +--- pantheios-1.0.1-beta214
                   +--- include
                   |       +--- b64
                   |       +--- pantheios
                   |       +--- shwild
                   |       +--- xtests
                   +--- lib

アプリケーションプログラムから利用する際にライブラリパスを絶対パスで指定しないで済むよう環境変数PANTHEONを定義しておきます。

これで準備はひとまず完了です。

はじめてのPantheon(VC++10編)

まずはHello worldのメッセージをログで出力するサンプルを作成し、ビルド、実行します。

Pantheiosは、ライブラリにwidestring(ワイド文字セット/Unicode用)があるとおり、マルチバイト文字セットとUnicode文字セットで異なる点があります。そこで、マルチバイト版、Unicode版と作成します。

HelloPantheiosA - マルチバイト文字セット版

Visual Studio 2010の新規プロジェクトで[Win32コンソールアプリケーション]を指定します。名前はHelloPantheiosAとし、プロジェクト設定はデフォルトのままで進めます。

プロジェクト設定

プロジェクトのプロパティを開き、構成欄を[アクティブ(Debug)]から[すべての構成]に変更し、左側ツリーの[構成プロパティ]>[全般]を選択し、右側ペインの文字セット欄を[マルチバイト文字セットを使用する]に変更します。

次にインクルードパスを指定します。プロジェクトのプロパティで、構成欄を[すべての構成]のまま、左側ツリーの[構成プロパティ]>[C/C++]>[全般]を選択し、右側ペインの追加のインクルードディレクトリの右側空白部分をクリックします。すると右端に[▼]が表れるので、これをクリックし、ドロップダウンメニューから<編集...>を選択します。

「追加のインクルードディレクトリ」ダイアログが出るので、[新しい行]アイコンを押し、STLsoftのインクルードディレクトリを入力します。

もう1回、[新しい行]アイコンを押し、PANTHEIOSのインクルードディレクトリを入力します。

次にライブラリを設定します。プロジェクトのプロパティで、構成欄を[すべての構成]のまま、左側ツリーの[構成プロパティ]>[リンカー]>[全般]を選択し、右側ペインの追加のライブラリディレクトリ欄の右側空白部分をクリックします。すると右端に[▼]が表れるので、これをクリックし、ドロップダウンメニューから<編集...>を選択します。

「追加のライブラリディレクトリ」ダイアログが出るので、[新しい行]アイコンを押し、Pantheiosのライブラリディレクトリを入力します。

プロジェクトのプロパティで、構成欄を[すべての構成]から[アクティブ(Debug)]に変更し、左側ツリーの[構成プロパティ]>[リンカー]>[入力]を選択し、右側ペインの追加の依存ファイル欄の右側部分をクリックします。すると右端に[▼]が表れるので、これをクリックし、ドロップダウンメニューから<編集...>を選択します。

「追加の依存ファイル」ダイアログが出るので、リンクするPantheiosのライブラリファイル名を入力します。Pantheiosのライブラリは多数あり、利用したい機能に応じて選択するようになっています。今回は最初のサンプルなので、次の画面のように指定します。

プロジェクトのプロパティで、構成欄を[アクティブ(Debug)]から[Release]に変更し、左側ツリーの[構成プロパティ]>[リンカー]>[入力]を選択し、右側ペインの追加の依存ファイル欄の右側部分をクリックします。すると右端に[▼]が表れるので、これをクリックし、ドロップダウンメニューから<編集...>を選択します。

「追加の依存ファイル」ダイアログが出るので、、今回は最初のサンプルなので、次の画面のように指定します。

ソースファイルの作成

Visual C++のプロジェクト作成時に雛形のソースコードが生成されています。

// HelloPantheiosA.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
        return 0;
}

ロギングAPIを定義しているヘッダーをインクルードします。

#include <pantheios/pantheios.hpp>

プロセス識別子(プロセス名)を定義します。この定義はpantheiosのライブラリ(FE)内で参照するので、グローバル変数として定義しextern "C"宣言します。

PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = 
        PANTHEIOS_LITERAL_STRING("HelloPantheiosA.exe");

ログを出力する文を記述します。

        pantheios::log_NOTICE("Hello, Pantheios world");

これらを記述した結果のソースコードが次になります。

// HelloPantheiosA.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <pantheios/pantheios.hpp>

PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = 
        PANTHEIOS_LITERAL_STRING("HelloPantheiosA.exe");

int _tmain(int argc, _TCHAR* argv[])
{
        pantheios::log_NOTICE("Hello, Pantheios world");
}
コードの補足説明

Visual C++の機能でプリコンパイルヘッダーを有効にしているときは、変更しないヘッダーファイル(システムやサードパーティライブラリ等)の#include指令をstdafx.hの中に記述します。stdafx.hに記載したヘッダーファイルがプリコンパイルヘッダーの対象となります。pantheiosのヘッダーで複数のソースファイルからインクルードするものについてはstdafx.hに記述する方がよいでしょう。

ビルドおよび実行

ビルドします。成功したら、生成された実行ファイル(HelloPantheiosA.exe)を実行します。

C:\work\HelloPantheiosA> debug\HelloPantheiosA.exe
[HelloPantheiosA.exe.5692, 2012/09/26 1:07:16.983; Notice]: Hello, Pantheios world

C:\work\HelloPantheiosA>

コンソールに、プロセス識別子、日時、ログレベル、メッセージ が表示されます。

HelloPantheiosW - Unicode文字セット版

Visual Studio 2010の新規プロジェクトで[Win32コンソールアプリケーション]を指定します。名前はHelloPantheiosWとし、プロジェクト設定はデフォルトのままで進めます。

プロジェクト設定

インクルードパスの設定、追加のライブラリディレクトリの設定は、HelloPantheiosAの場合と同じになります。

追加の依存ファイルは、widestring版のライブラリファイルを指定します。

ソースファイルの作成

Unicode文字セットを使う場合、pantheios::log_NOTICEの引数の文字列リテラルに、Windowsのtchar.hで定義されるマクロ _T("...")を使用している点が異なります。この_T("...")は、ワイド文字列リテラルを指定するL"..."に展開されます。

// HelloPantheiosW.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <pantheios/pantheios.hpp>

PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = 
        PANTHEIOS_LITERAL_STRING("HelloPantheiosW.exe");

int _tmain(int argc, _TCHAR* argv[])
{
        pantheios::log_NOTICE(_T("こんにちは、Pantheios"));
}
コードの補足説明

今回バックエンド(ログ出力先)にWindowsConsoleを指定しているので、上記コードで日本語も表示されていました。

バックエンドにfprintf(ライブラリpantheios.1.ber.fprintf.vc10.widestring.dll.lib)を指定すると、日本語が文字化けします。setlocaleを最初に実行しておきます。

        setlocale(LC_ALL, "japanese");

ビルドおよび実行

ビルドします。成功したら、生成された実行ファイル(HelloPantheiosW.exe)を実行します。

C:\work\HelloPantheiosW> debug\HelloPantheiosW.exe
[HelloPantheiosW.exe.6112, 2012/09/26 1:42:58.797; Notice]: こんにちは、Pantheios

C:\work\HelloPantheiosW>

コンソールに、プロセス識別子、日時、ログレベル、メッセージ が表示されます。

pantheiosプログラミングTips

名前空間pantheiosが長い

<pantheios/pantheios.hpp>の代わりに、<pantheios/pan.hpp>をインクルードします。

pantheios::log の代わりに、pan::log とコードを書けます。

リンクするライブラリの変更が面倒

バックエンドやログのフィルタを切り替えるには、リンクするライブラリを変更する必要があります。

Visual Studioのプロジェクトでライブラリ名を変更するのは以外と面倒です。

Pantheiosには、ヘッダーファイルのインクルードでリンクするという手段が用意されています。先のHelloPantheiosサンプルコードのリンク設定と同じことは、次のインクルードで実現できます。

#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.WindowsConsole.h>

このインクルードを記述しておけば、プロジェクトにライブラリのリンク設定を記載する必要はありません。