minimize

ロガー定義について

最近ではほとんどのアプリケーションでログ出力が行なれていると思います。

private static final Log LOG = LogFactory.getLog(Foo.class);

この1文こそが、Javaの数少ない弱点のうちの一つを表しています。
多重継承もマクロも使えないJavaでは、この1文を全てのクラスに記述しなければなりません。
しかも、Foo.class の部分はクラス毎に変える必要がある為
コピペで作成されたクラスなどはこの部分が適切に変更されていない場合もあります。

一番確実な方法は、Eclipseだったらテンプレートを使うことです。
こうすればミスも無く、簡単です。
以下のようなテンプレートを登録しておきましょう。

private static final Log LOG = LogFactory.getLog(${enclosing_type}.class);

また、Eclipseの場合はクラスをコピーする時に
Foo.class の部分を自動的に変えてくれます。

PMD : ProperLogger

ログ出力のポリシー

ほとんどのプロジェクトで、ログの出力内容には
統一された決まりが無く、ただ個人の気まぐれで出力している
ケースというのも多く見られます。

Log4jを含め、通常のログライブラリは出力レベルというものがあります。
最大限のログ出力をコード内に記述して
実際にログ出力をするのは、環境に応じた出力レベルのものに
限定するという考え方です。

ライブラリのような共通プロジェクトでは
このやり方は比較的うまく使われています。
しかし、通常のプロジェクトでも同様の手法で
うまくいくとは限りません。僕の経験では、ほとんどうまくいっている例は無いです。

個人的見解

僕の考えでは、ログレベルによるログ出力がうまくいくのは
他のロジックから使われるような「共通ロジック」に限られると思います。
末端にある独自ロジックにおいて、適切にログレベル制御された
ログ出力を行うのは非常に厳しいです。

ほとんどのプロジェクトでは、何らかのフレームワークの上で
各プログラムが動いています。
ですから、ログ出力はこれらフレームワークに任せ
各プログラム上ではデバッグ用途のログを出力する程度に留めた方がいいでしょう。

ここで言っているデバッグログというのは、

logger.debug(...);

でも良いし

System.out.println(...);

という「標準出力」へのログでも良いです。
ただし、標準出力へのログ記述はコミット時には必ず削除しておきましょう。

debug() と System.out の使い分けですが
前者はリリース時に必要となるかもしれないものを出力し
後者は開発時に一時的に必要なものを出力します。

標準出力について

開発時だからといって、標準出力へのログを拒否して
全てを debug() で済まそうという考えは僕は好きではありません。
なぜなら、そういったログはコミット時に
全て削除されてしまう傾向にあるからです。

debug() と System.out を使い分けることにより
必要なログと不必要なログを区別することが出来ます。
後者を Checkstyle などでチェックしておけば
コミット時に残したままリリースしてしまうという危険も防げます。

リモートデバッグ

最後に。
Javaプロジェクトでは簡単にリモートデバッグが行えるので
全てをログ出力だけで解決しようというのは
あまりスマートな方法ではありません。

しかし、セキュリティなどの理由から
リモートデバッグが出来ない場合も多々あるはずですので
そういう場合にはこういった古典的なログによるデバッグに頼るしか無いでしょう。

[コメント(0)]