[ C++で開発 ]
プログラムの開発・保守に欠かせない機能が「ロギング」です。開発中のデバッグ効率や、運用中の障害解析に、ロギングの機能が効いてきます。しかしながら、これを使えば、という定番がないのがC++の現状です。
ロギングライブラリには、ロギング機能のみを提供するロギング単体ライブラリと、フレームワークの一部としてロギング機能を提供するものがあります。
ログレベル、カテゴリ(分類)によるログ出力有無・出力先の設定
ログファイルのローテーション
出力形式の設定(タイムスタンプの分解能・時刻帯の指定、ロケール、他)
ログ出力コーディングの簡潔さ
コンソール、ファイル、ネットワーク、システムログなどへの出力手段
性能への考慮
ライブラリのメンテナンス状況
リリース状況
Windows上のVC++は、VC++8以降でないとコンパイルが通らない。原因はLocaltime.cppがVC++7.1以下を考慮していないため。具体的には、マクロ_MSC_VERの数値でバージョンを判定すべきところを、単にマクロ_MSC_VERが定義されていれば、VC++8以降で追加されたlocaltime_s関数を呼ぶようになっているから。修正としては、以下のようにコンパイラバージョンにより実行コードを変える。
// 修正結果 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && defined(LOG4CPP_HAVE_LOCALTIME_R) void localtime(const ::time_t* time, ::tm* t) { localtime_s(t, time); } #end // 中略 #if defined(_MSC_VER) && (_MSC_VER < 1400) || !defined(LOG4CPP_HAVE_LOCALTIME_R) void localtime(const ::time_t* time, ::tm* t) { ::tm* tmp = ::localtime(time); memcpy(t, tmp, sizeof(::tm)); } #endif
簡単な使い方については次のページに記載しています。
リリース状況
Apache財団のプロジェクト。ライセンスはApache License 2.0、外部ライブラリ APR(The Apache Portable Runtime Library)を必要とする。ログ設定ファイルの書式は、log4j互換。
デバッグログ出力例
LOG4CXX_DEBUG(logger, "Hello, my name is " << name);
ビルド時にsedコマンドを使用するので、Windows上でsedコマンドがない場合、sedを入れるか手作業で修正する必要がある模様。
リリース状況
リリース状況
別途ライブラリ STLSoftを必要とする。ライセンスはBSD-style。
C/C++のAPIを持ち、バックエンドに他のログライブラリを使用することもできる。元々はSynesis Software社の中で使われたログ機構から分派し、BSDライセンスのもと、商用・非商用問わずフリーで使えるオープンソースとなった。
ログの出力先として、ファイル、標準(エラー)出力、SysLog、Windowsデバッガ、Windowsイベントログ、COMエラーオブジェクト、スピーチなどをサポートしている。Pantheiosのバックグラウンドに他のロギングライブラリを使用することもできる。
UNIX(Linux、Solaris、FreeBSD)、Mac OS X、Windows上で動作し、各種コンパイラ(Borland、Comeau、Digital Mars、GCC、Intel C++、Metrowerks、Visual C++)に対応する。
リリース状況
Googleのプロジェクト。ライセンスはBSD License。
WindowsはVC++8以降(localtime_sなどが使われている)
<windows.h>に定義されるERRORとマクロが衝突する。要回避策(glogのWebサイトに記載あり)
ロギングライブラリの性能比較を行っている。ACE、Boost.Log、log4cpp、log4cplus、log4cxxとPantheiosの比較。
Pantheios開発者による比較記事なのでバイアスがかかっているものとして見る必要がありますが、十分参考になります。
C++標準ライブラリに、std::clogおよびワイド文字版のstd::wclogがあります。これは、標準エラー出力にバッファリングありで出力するものです。ライブラリが使えない場合に、このstd::clogをファイルに出すよう設定すれば、簡易ログ機能になります。
ただし、ログレベルや複数の出力先、ファイルローテーションといった機能はありません。
#include <iostream> #include <fstream> int main(int argc, char* argv[]) { std::ofstream logFile("myapp.log"); if (logFile) { std::clog.rdbuf(logFile.rdbuf()); } std::clog << "Hello, clog world!" << std::endl; }