Log4J徹底解説

OSログ系Appender

目次

SyslogAppdender

SyslogAppender は 1.2.14 以降で、SMTPAppender と並んで追加の多い Appender である。それらについては1.2.14以降の新仕様で検討する。

さて、これは org.apache.log4j.net.SyslogAppender であることからも判るように、実際にはネットワーク系の Appender である。つまり、root でこれを使ったアプリを動かしても、ローカルマシンの syslog で取り扱って貰えるわけではない、ということを最初に言っておこう。

じゃ何で「Syslog」なんだ、というと、標準的な UNIX の syslogd には、「リモート受信モード」があるんである。つまり、リモートログサーバ用の仕様のわけだ。ログを外部のサーバに送信して、二重化することで、ログの改竄を防ぐ、というわけである。大概リモートログサーバっていうと、時代遅れのマシンで他にはロクなサービスも起動せずに(これは侵入防止)、ひたすらログ取りのためにご奉仕する、ということが多いが、そういう用途で最初から syslogd にこの仕様があるんである。

ただ、フツーの UNIX マシンではデフォルトでこの「リモート受信モード」が有効になっていることはないだろう。SyslogAppender で遊ぶためには、まず、この「リモート受信モード」を有効にして、ネットワークから(514/udp)の受信を可能にしてやる。また、多少設定ファイルの /etc/syslog.conf を修正する必要もあるので、先にこれをやろう。

/etc/syslog.conf は基本的にこんな構造のファイルだ。

#facility.level[;faclity.level...]        TAB+          action
*.info;mail.none;authpriv.none                          /var/log/messages
mail.*                                                  /var/log/maillog
*.emerg                                                 *

要するに「facility」というのは、log4j で言えば「カテゴリー名」であり、「level」は「ログレベル」だ。それぞれの組合せ(ワイルドカードで「*」が使える)に対して、「action」を設定可能で、大概はタダのファイル名だ。タダのファイル名だったらそれはタダのログファイル名であるが、「@ホスト名」だったらクライアントとして外部ログサーバに送信するわけである。「*」だったらこれは非常に楽しい結果が訪れるので一度実験してみるといいかな?(苦笑)。きっと「びっくり!」すること請け合いだ...要するにすべてのコンソールにメッセージが表示され、ベルが鳴るんである。要するにカーネルパニックとかとんでもない状況になったときに、カーネルは努力してそれを全ユーザに伝えようとするわけだ。

「facility」には「authpriv」(認証関連)とか「mail」とかいろいろあるが、特にユーザ用途として「local0〜local7」が定義されている。だから、まあ、「local0〜local7」を使うのが無難と言うものだ。ただし、RedHat系だと「local7」はブート時メッセージを出すのにディストリビューションが使っているので、結果として「local0〜local6」が「無難」ということになる。

で、「level」は当然 log4j のログレベルと同じものだが、名前がやはり違うので、そのマッピングを書いておこう。

sysloglog4j
emergfatal
errerror
warningwarn
noticeinfo
infoinfo
debugdebug

で、/etc/syslog.conf に追加する行はこんなもんだろう。この出力は /var/log/log4j.log に出る。

local6.*						/var/log/log4j.log

/etc/syslog.conf を直したら、「リモート受信モード」で syslogd を起動し直す。RedHat 系 Linux だと、

# /etc/rc.d/init.d/syslog stop
# /sbin/syslogd -r

でとりあえず遊ぶ準備は整う。

SyslogAppender のオプションは次の通りだ。

SyslogHost
リモート受信モードの syslogd が起動しているリモートログサーバのマシン名。1.2.14 で仕様が追加され、ここの表現としてログサーバのポートを指定できるようになった。後述
Facility
使うfacility名。今回の設定だと「local6」である。
FacilityPrinting(1.3 Deprecated)
boolean値。ログに facility も一緒に出力するかどうかのフラグ。デフォルトは false で出力しない。1.3 では deprecated 扱いになり、このオプションは無効化されている。
Header(1.2.15以降)
値は true or false。これはログに対してタイムスタンプとホスト名を追加するかどうかのフラグである....が実はこれがなぜ追加されたか、というと少しややこしい。後述
Threshold
(AppenderSkeltonから継承)

なので、遊ぶ設定ファイルはこんなとこだ。

log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
log4j.appender.syslog.Facility=local6
log4j.appender.syslog.SyslogHost=localhost
log4j.appender.syslog.FacilityPrinting=true
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern=%5p %c{1} - %m%n

log4j.rootLogger=debug, stdout, syslog

で、注意事項は ConversionPattern だ。実際には syslogd の側で受信時間を含めてロギングするので、ConversionPattern に「ログ発生時間」を含めちゃうと時間がダブってうっとおしい。だからわざと時間(%d)は落してある。

遊ぶ時の注意事項! /etc/syslog.conf に、

*.info;mail.none;authpriv.none                          /var/log/messages
*.emerg                                                 *

の2行があることにお気づきかな? ということは、log4j の info() 以上のログを生成した時には、/var/log/messages にも書き込まれるのである。ひょっとして何か重要な仕事をしているサーバで遊んだ場合、管理者に叱られる可能性がないわけじゃないぞ! また、fatal() を生成した時には「emerg」になる。これは大変目立つ効果を伴うが、そのためにやはり管理者に叱られるかもしれないぞ。また、筆者の環境だと、Xサーバを起動した状態で fatal() を生成した時、どうも調子が悪いようだ。そりゃ設定によっては emerg 生成でXの画面がフラッシュする、という風になっているケースもあるわけで、それが障害のきっかけにならないとも言えない。まあ、「政治的」にも注意してやってくれ。

あと、一般的な注意事項としては、このリモートログサーバ機能についてのものがある。これは UDP を使っているので、いわゆる「確実性のないプロトコル」である。ひょっとしてパケットを落すかもしれないし、落しても気づかない。あと当然認証とかもないので、当然「LAN内部だけで使ってくれ!」の代表的なサービスである、ということを忘れないでくれ。

で、この SyslogAppender は 1.3 ではほとんどオプションの変更はない(FacilityPrinting オプションが無効になった)だけだが、詳細動作は大幅に変わっている。たとえば、1.2 系では SyslogAppender は「Syslog パケットを送る!」というだけのものだったが、1.3 では、

2006-04-02 18:31:53,741 DEBUG SyslogWriter - Writing out 
[<190>Apr  2 06:31:53 bizet  INFO TestLog4j - EXIT: TestLog4j]

というようなログを DEBUG レベルで自動的に出す。また、ちょっとしたプロローグを付けて Syslogd に向けて送信するなんていう仕様も追加されている。比較してみると、

Apr  2 18:27:48 localhost bizet  INFO TestLog4j - ENTER: TestLog4j 1.3
Apr  2 18:30:57 localhost  INFO TestLog4j - ENTER: TestLog4j 1.2

で、Apr 2 18:27:48 localhost は syslogd が勝手に付け加える日時・受けたホスト名であり、bizet は 1.3 系 log4j が自動的に付け加えるホスト名になっている。動作の違いの見掛けはわずかだが、実際には結構手が入っている。

SyslogAppdender(1.2,14以降の新仕様)

1.2.14 以降では、ここらへんに少し改善がなされた。問題は、syslogd が勝手に行うログ情報と、PatternLayout との相性がイマイチ、ということにある。先程の例でも、通常と違って日時情報(%d)をわざと入れない...とかしていたが、ここらへんをPatternLayout なしでやっちゃおう、というのが、どうやら今後の SyslogAppender のやり方になりそうだ。

だから新規追加の Header オプションを true にすると、日時とホスト名とを自動的に追加されることになったわけだ。新しい設定法はこんな感じだ。

log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
log4j.appender.syslog.Facility=local6
log4j.appender.syslog.SyslogHost=localhost
log4j.appender.syslog.FacilityPrinting=true
log4j.appender.syslog.Header=true
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout

異常なことに、layout 要素だけあって、ConversionPatter は指定しない。これで出力は、

Sep 15 11:09:44 bizet bizet.kobe-du.ac.jp local6:引数出力(%m相当)

になる。要するに、layout 要素がないと、一応 layout 必須のAppender ということになっているので、まずいわけだ。だから互換性との関連でこういうヘンテコな書き方をすることになる。勿論、レガシーな書き方もそのまま通るわけである。

で、SyslogHost オプションの中で、ポート番号を指定できるようになった。これはこんなところである。

log4j.appender.syslog.SyslogHost=localhost:9999

単なる URL 表記の準用なのでこれは分かりやすい。しかも、IPv6 をニラんで、

log4j.appender.syslog.SyslogHost=[127.0.0.1]:9999

みたいな表記(IPv6 のIPアドレス表記に合わせた URL 表記)も通る。

ただし、syslogd ではフツー -p オプションで代替ポートを見るようにしてリモートモードで起動する、というかたちで書かれていないので、9999 みたいなポート番号で syslogd をリモートモードで起動するには、/etc/services の syslogd の監視ポートを書き換える必要がある。

#syslog		514/udp
syslog		9999/udp

NTEventLogAppdender

さて、こんどは UNIX じゃなくて WNT だ。WNT には「NTイベントログ」というロギング機能があって、ペケポンだと「コントロールパネル」〜「管理ツール」〜「イベントビューア」〜「アプリケーション」で、生成したログを見ることができる。こんなもんだ。


NTEventLogAppender は当然実行マシンの「NTイベントログ」に追加する。だから、SyslogAppender がネットワーク系Appender だったのは少々訳が違う。

で、これを使うためにはちょっと準備が要る。フルパッケージ版を解凍すると、src/java/org/apache/log4j/nt/NTEventLogAppender.dll があるので、これを c:\WINDOWS\system32 に入れておいてやる。要するに別にDLLが要るんである。

で、log4j.properties のオプションはこんなものだ。

Source
ログを生成したアプリケーション名。テキトーな名をつけてやる。
Threshold
(AppenderSkeltonから継承)

簡単だな。一応レイアウトは有効なので、レイアウトは書いておいた方が良かろう。で、SyslogAppender と同様、「log4j のログレベル=イベントログのログレベル」じゃないので、マッピングを書いておこう。

NTEventLoglog4j
エラーfatal, error
警告warn
情報info,debug

で、log4j からイベントを生成すれば、NTイベントログに追加されるのが判ると思う。

でも何でこんなヘンテコなログシステムなんだろう? はっきり言って判りづらいぞ。プレーンテキストで何が気に入らないんだろう??? M$ のやるこたぁ俺ぁ判らんぞ。



copyright by K.Sugiura, 1996-2006