Log4j

言わずと知れた jakarta のログAPI。前に一度使おうとして、ドキュメントを読んだけどわかりにくかったので断念。
今回、プロジェクトで使用するため少しばかり調査したので、普通のドキュメントからわかりにくい部分をまとめた。(自分が使うところだけ)
※ あ、対象は Log4j 1.1.3

1. DEBUGレベルと、INFO以上でログを分ける

Log4jでは設定ファイルを使用してカスタマイズできる。まず、マニュアルに載っている通りに以下のような設定ファイルを書いた。
log4j.rootCategory=DEBUG,FILE,NT

# デバッグログファイルの設定
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.Threshold=DEBUG
log4j.appender.FILE.File=debug.log
log4j.appender.FILE.Append=true
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d %c %m%n

# INFO以上のログのNTイベントログの設定
log4j.appender.NT=org.apache.log4j.nt.NTEventLogAppender
log4j.appender.NT.Threshold=INFO
log4j.appender.NT.layout=org.apache.log4j.PatternLayout
log4j.appender.NT.layout.ConversionPattern=%c %m%n
これで、DEBUG以上は、debug.logに、INFO以上は NT のイベントログに出る。
しかし、やりたかったことはデバッグログはファイルだけ、INFO以上はNTのイベントログに出したかった(これでは、ファイルにINFO以上も出てしまい、だぶってしまう)
マニュアルによると、Filterを使えばできるらしいことが書いてあり、サンプルへのリンクがあるのだが、そのリンクが切れている!
いろいろと試行錯誤して、PropertiesConfiguratorのAPIリファレンスに「複雑なことをやりたければ DOMConfiguratorを使え」と書いてあったこともあり、リンク切れのサンプルを探すことに。ファイル検索で、test11.xmlを探すと、ソースツリーの方にあった。
このサンプルを見て、さらに DOMConfiguratorの API リファレンスと、log4j.dtd を見た結果、以下のコンフィグファイルができた。
<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
  <!-- INFO以上のログのNTイベントログの設定 -->
  <appender name="NT" class="org.apache.log4j.nt.NTEventLogAppender">
    <param name="Threshold" value="INFO" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%c %m%n"/>
    </layout>
  </appender>

  <!-- デバッグログファイルの設定 -->
  <appender name="DEBUG" class="org.apache.log4j.FileAppender">
    <param name="Append" value="true" />
    <param name="File"   value="debug.log" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d %c %m%n"/>
    </layout>
    <filter class="org.apache.log4j.varia.PriorityMatchFilter">
      <param name="PriorityToMatch" value="DEBUG" />
      <param name="AcceptOnMatch" value="true" />
    </filter>
  </appender>

  <root>
    <appender-ref ref="NT" />
    <appender-ref ref="DEBUG" />
  </root>
</log4j:configuration>
これで、DEBUGレベルだけがファイルに出るようになった。

ちなみに、ソースの初期化部分は、以下のような感じ。
※ URL を使用しているのは、WEBアプリで使いやすくするため。下記の設定で、CLASSPATH直下のlog.xmlを読み込む。
    URL url = Log.class.getResource("/log.xml");
    DOMConfigurator.configure(url);
    // PropertiesConfigurator.configure(url);

2. NTのイベントログの「ソース」に出るLog4jを変える

デフォルトでは、イベントビューアで見たとき「ソース」の部分に「Log4j」と出る。
これを、ログを出力するシステムの名前にしたかった。しかし、ドキュメントを見てもやっぱり良くわからなかった。(マニュアルには、各appenderのAPIリファレンスに書いてあると書いてあったが、読んでも良くわからなかった。)
しかし、読むところはマニュアルとソースくらいしかないので、もう一度良く読み直すと、setSource(String)と言うメソッドがあったので、設定ファイルのNTの部分を以下のように変えてみた。
  <appender name="NT" class="org.apache.log4j.nt.NTEventLogAppender">
    <param name="Threshold" value="INFO" />
    <param name="Source" value="ほげほげシステム" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%c %m%n"/>
    </layout>
  </appender>
これで、「ソース」の部分に「ほげほげシステム」が出るようになった。

※ イベントビューアには、他に「分類」と「イベントID」が出る。ここをうまく意味のある文字列にすることはできないか?

3. デバッグログが出力されないようにする

本運用時には、デバッグログには出て欲しくないものだ。
とりあえず、以下のようにするとデバッグログが出ないし、Category.isDebugEnabled()もfalseを返すことを確認した。
※ これが正しいかわからないし、他にもたくさん方法がありそうだ。
  <root>
    <priority value="INFO" />
    <appender-ref ref="NT" />
    <appender-ref ref="DEBUG" />
  </root>

4. NTのイベントログ

余談かも知れないが、上の設定でNTのイベントログを使うには、動作OSがWindows NT系であることと、src\java\org\apache\log4j\nt\NTEventLogAppender.dll を Windowsディレクトリの system32の下にコピーしておく。
※ Java実行時のPATHに入っていれば実行はできるが、イベントサービスのパスにも入ってないとまずそう。
false@wizard-limit.net