ログ設計は難しい

デバッグ、コードリーディング、構成管理、例外あたりは情報が近年でつつあるように思う。ただログに関してはあまり見ない。

開発時にはほとんど考慮されず保守で必要なログが出ていないで困るというパターンが多い。

開発と保守では担当する人が異なることが多く(しかもどちらも協力会社まかせだったりする)、保守経験が無くて開発ばっかりやってるとログに関するノウハウが蓄積しないし、必要性もわからなかったりします。

まあそんなわけで(どんなわけで?)、ログに関してこうやればいいんじゃない的なものを書いてみたいと思います。

とりあえずAOPによるログ出力は強力です。これは実感しています。ただ効果を最大限にするには呼び出されるメソッド名だけを出力してもあまり意味が無い。引数や戻り値、例外が発生したならそれも出力してはじめて効果を発揮する。
引数や戻り値は単純なStringやintとかだけではなくてList、Map、配列の要素も出力する。beanの中身もリフレクションやcommons-langのToStringBuilderを活用して出力する。つまりログにハッシュがでないようにする。共通的にやれば1個1個toStringをオーバーライドする必要も無い。
もちろんAOPを使ったからといって個々の開発者によるロギングは不要になるわけではありません。AOPだとprivateやfinalメソッドはロギングできないし、もっと詳細な意味のある業務ログは個別実装しかないと思っています。
あとログに出してはまずい機密情報があればそれはマスクする。Webアプリならスレッド名やログインしているユーザIDも出力する。

ログは肥大化するので日ごとにローリングすることになると思いますが、それ以外にもレベルやレイヤーごとにファイルを分けることもあると思います。

if(Logger.isXXEnabledは書くのがわずらわしいのでつかわずにSeasarのようにプロパティファイルのプレフィックスでレベルを切り分ける。

だいたいこんな感じかな。

あと関連することとしてメッセージの管理があるのですが、Excelマクロでプロパティファイルとソースを自動生成するプロジェクトを経験したのですが、あまりうまくいってないような気がします。面倒だし差分が見にくい。自動生成のもとと成果物に乖離が発生しやすい。納品時にExcelが必要ならむしろプロパティファイルかソースから自動生成したほうがいいと思う。

Excel以外のやり方は2つあると思っていてプロパティファイルからソースをAntなりMavenなりで自動生成し、自動生成されたものは構成管理対象外とする。Hudsonはこの方式だね。あるいは逆にソースのjavadocコメントからプロパティファイルを自動生成する。docletつかって自動生成しているプロジェクトは見たことがある。

こういった細かいことは面倒だけど何回もやる作業なのでうまく効率化していきたいね。