logbackを使う
今まではJavaでログ出力といえば、log4jだったが、最近ではlogbackも使いやすくなっている。
[追記]
logbackはintra-martで採用されたりしているので既にかなりメジャーであると言える。
http://www.intra-mart.jp/apilist/v70/doclet/im_commons/jp/co/intra_mart/common/platform/log/rolling/ExtendedTimeBasedRollingPolicy.html
[追記-終]
logbackでログをファイル出力する場合は下記のAppenderクラスを使う。
- FileAppender - ファイルへ出力する。
- RollingFileAppender - FileAppenderを継承し、ログローテーションを提供する。
詳細はリンクを参照。
logbackではログローテーションを実現する際に、RollingPolicyクラスとTriggeringPolicyクラスというものを使うことになる。
簡単にいうと、RollingPolicyはローテ時のバックアップファイル名についての規定を提供。
TriggeringPolicyはログローテーションのローテタイミングについての規定と機能を提供、という感じ。
ローテーションを実現するにはRollingPolicyとTriggeringPolicyの2つを定義する必要がありそう、とここでイメージできる。
主なRollingPolicyクラスは以下
日次ローテ、毎時ローテなどを提供する。
TimeBasedRollingPolicyはTriggeringPolicyとRollingPolicyが同居する。(つまり定義一つでOK)
バックアップファイル名をlog.1,log.2の形で作成できる。
別にSizeBasedTriggeringPolicyを定義する必要がある。
日時ローテとサイズローテを組み合わせたい場合に使う。
使いたい場合は、TimeBasedRollingPolicyの中に組み込む形で定義するようだ。
詳細はリンクを参照。(サンプル有り)
主なTriggeringPolicyクラスは以下
言わずもがなサイズローテーション用TriggeringPolicy。
FixedWindowRollingPolicyと併用。
logbackがlog4jより良い点として、"複数のJVMによる同じログファイルへの書き込みをサポートしている"というところだろう。
FileAppenderに"prudent"(boolean)という設定項目がある。
デフォルトではfalseだが、trueにすることで、複数プロセスで同じログファイルへの出力を保証するモードを利用できる。
log4jでは複数プロセス(マルチJVM)で同じログファイルへ出力するとログが消えるなどしてしまう。
ちなみにprudent=trueの場合は通常ログ書き出しメソッド(OutputStreamAppender#writeOut)でなく、
独自のFileAppender#safeWriteメソッドを使う。
safeWriteはこれだ。
final private void safeWrite(E event) throws IOException { ResilientFileOutputStream resilientFOS = (ResilientFileOutputStream) getOutputStream(); FileChannel fileChannel = resilientFOS.getChannel(); if (fileChannel == null) { return; } FileLock fileLock = null; try { fileLock = fileChannel.lock(); long position = fileChannel.position(); long size = fileChannel.size(); if (size != position) { fileChannel.position(size); } super.writeOut(event); } finally { if (fileLock != null) { fileLock.release(); } } }
つまりFileChannelで排他ロックを取りながらログ出力をする。
処理速度にいちゃもんが付きそうだが、正確にログが取りたい場合は使いたいところだ。
また、logbackはslf4jというライブラリとセットで利用する。
ほとんどslf4jを使うことを意識する必要はないが、introductionを参照して理解しておくと良い。
また日本語サイトでは、ここもslf4jのロガー実装切替アルゴリズムが理解できる。