torutkのブログ

ソフトウェア・エンジニアのブログ

log4cppの設定ファイル

以前Webページに、SimpleConfiguratorによるログ設定ファイルの記述方法を記載しています。log4cppには、このSimpleConfiguratorの他に、もう一つPropertyConfiguratorによるログ設定ファイルの記述が可能です。

SimpleConfiguratorでは、カテゴリの階層化ができず、出力レベルはカテゴリ名とぴったり一致したものをログ設定ファイルに定義する必要がありました。
また、SimpleConfiguratorはdeprecated(非推奨)となっているので、本格的にlog4cppを使用するならPropertyConfiguratorを使うべきでしょう。

しかし、PropertyConfiguratorの使い方については情報がほとんどありません。log4jの設定と等価だ、ということ以外は、Web上にわずかに散見できる程度です。

そこで、PropertyConfiguratorを使った際のログ設定ファイルの書式を、実験およびlog4cppのソースコードから調べたメモを記載します。いずれWebへ整理して記述する予定です。

階層化

大きなプログラムでは、すべてのログを一気にOn/Offする単純なやり方ではなく、最低限ログレベルで出力を何段階かで制御できるようにします。おおよそ10万行規模まではこれで何とかなります。

しかし、さらに大きなプログラムでは、レベル制御だけでなく、サブシステム(パッケージ、機能、他の分割単位)でログの出力レベルや出力先を制御したくなります。このとき、カテゴリ名の階層化による指定ができないと、すべてのカテゴリ名をログ設定ファイルに列挙してそれぞれごとに設定を記述することになります。

そこで、階層化したカテゴリ名により、中間階層でログ設定をすれば、それ以下の階層は自動的に設定され、かつ、下位階層のログ設定を記述すればそのカテゴリにだけ設定が反映される仕組みを使います。

rootCategory=WARN, CONSOLE
category.view=NOTICE, LOGFILE
category.view.event=DEBUG
  • デフォルトの(ルート)カテゴリは、優先度WARN以上のログをアペンダ名"CONSOLE"に出力する設定
  • "view"カテゴリは、優先度NOTICE以上のログをアペンダ名"LOGFILE"に出力、但しルートカテゴリで設定されているアペンダ名"CONSOLE"にも出力する。
    • ルートカテゴリの優先度はWARNだが、viewカテゴリがNOTICEであり、NOTICE
  • "view.event"カテゴリは、優先度DEBUG以上のログを、上位階層の"view"カテゴリで設定されているアペンダ名"LOGFILE"に出力、ルートカテゴリで設定されているアペンダ名"CONSOLE"にも出力する
  • "view.event"以外のview下の階層("view.printer"など)は、特に設定記述がないので、"view"の設定に従う

アペンダは複数設定可能です。

category.view.dialog=INFO, CONSOLE, LOGFILE
additivity.view.dialog=false
  • カテゴリ"view.dialog"は、優先度INFO以上のログをアペンダ名"CONSOLE"および"LOGFILE"の双方へ出力する。
  • カテゴリ"view.dialog"は、上位階層の設定を継承しない(additivityの設定をfalseにしているため)

上記でadditivityを設定しないと、カテゴリ"view.dialog"によるアペンダ"CONSOLE"出力およびカテゴリルートによるアペンダ"CONSOLE"の2つが適用されるため、CONSOLEに2重に出力されることになります。

アペンダの設定

設定例は以下です。

appender.CONSOLE=ConsoleAppender
appender.CONSOLE.layout=BasicLayout

1行目は、アペンダ名"CONSOLE"のアペンダ種類を指定しています。

2行目は、アペンダ名"CONSOLE"の属性layoutを指定しています。

アペンダの種類

アペンダは以下の種類が設定可能です。

種類 内容 備考
ConsoleAppender コンソール出力
FileAppender ファイル出力
RollingFileAppender 設定上限サイズで設定世代分ローテーションするファイル出力
SyslogAppender リモートsyslogサーバへ出力する
LocalSyslogAppender 同一ホストのsyslogへ出力する
AbortAppender
IdsaAppender
Win32DebugAppender WindowsOSのみ有効
NTEventLogAppender WindowsOSのみ有効
アペンダの属性

アペンダには属性を伴うものがあります。

属性名 適用アペンダ種類 内容 デフォルト値 備考
fileName FileAppender, RollingFileAppender ファイル名 foobar
append FileAppender, RollingFileAppender 追記モードか否か true
maxFileSize RollingFileAppender ファイル上限サイズ 10x1024x1024
maxBackupIndex RollingFileAppender ローテーション最大数 1
syslogName SyslogAppender, LocalSyslogAppender シスログ syslog
syslogHost SyslogAppender シスログホスト名 localhost
facility SyslogAppender, LocalSyslogAppender -1(LOG_USER)
portNumber SyslogAppender リモートのポート番号 -1(ポート:514)
idsaName IdsaAppender foobar
source NTEventLogAppender
threshold 全アペンダ アペンダに優先度の閾を指定する
layout 全アペンダ アペンダにレイアウトを指定する
アペンダのレイアウト

アペンダに設定可能なレイアウト種類は以下のものです。

レイアウト名 内容 備考
BasicLayout 規定のレイアウト %R %p %c : %m
SimpleLayout 規定のレイアウト %-6p : %m
PatternLayout 設定ファイルでカスタマイズ可能なレイアウト layoutのサブ属性ConversionPatternで指定

ConversionPatternで指定する書式指定子は以下のものです。

書式指定子 内容 備考
%c カテゴリ名 %c{1}とすると階層名の後から1つ目まで出力
%d 年月日時分秒ミリ秒 ロケール時刻で出力
%m メッセージ
%n 改行 改行がないと次のログが改行なしに出力される
%p 優先度 %-6pと桁数を指定して合わせる(-は左詰)
%r プログラム起動からの経過秒
%R エポック(1970/01/01からの経過秒)
%t スレッド名(アドレス?)
%u プロセッサ時間
%x NDC(スタックレベルによるインデント)

アペンダの指定例を以下に示します。

appender.LOGFILE=FileAppender
appender.LOGFILE.fileName=myapp.log
appender.LOGFILE.layout=PatternLayout
appender.LOGFILE.layout.ConversionPattern=%d %t %-6p %c - %m%n

コードの記述

ログ初期化
#include <log4cpp/PropertyConfigurator.hh>
...
log4cpp::PropertyConfigurator::configure("log4cpp.conf");
ログ出力
#include <log4cpp/Category.hh>
...
log4cpp::Category& logger = log4cpp::Category::getCategory("view");
logger.debug("hello, %s world", name); // C言語printfスタイル
logger << log4cpp::Priority::INFO << "yes " << name << " can!" <<
          log4cpp::eol; // C++言語iostreamスタイル
後始末
...
logger.shutdown();

shutdownを各カテゴリ毎に呼んであげないとflushされない