仕事でtomcat 6.0.xを使う機会があったのでtomcatのログ制御について調べた事をいくつか。

tomcatはいつからかtomcat-juliというログ吐きモジュールをtomcatに埋め込むようになっている。中身は単なるcommons-loggingだという事だが、重要なのはこれがjava.util.loggingとして動作する事だ。大儀ぃ・・・・。で、docs/logging.htmlを読むとtomcat-juli-adapterというアダプターにログを転送するtomcat-juliがあるのでそれに「置き換えろ」と書いている。だが、tomcatのバイナリディストリビューションを解凍して出来るRUNNING.TXTには${catalina.base}/binに代替tomcat-juliを置けと書いている。で、実際に${catalina.base}/binにtomcat-juliを置いてみると、${catalina.home}/bin/catalina.shではログの置き換えができるが、${catalina.home}/bin/commons-daemon-native.zipを解凍して出来るtomcat7.sh(tomcat6なのになぜかtomcat5.shとtomcat7.shしかない)ではログの置き換えができない。

ネット上を漁ると、「tomcatはログ出力モジュールとしてtomcat-juliがハードコードされている」と書かれているものが散見される。が、このハードコードというのは${catalina.home}/bin/bootstrap.jarのMANIFEST.MFにクラスパスとして書かれているだけで、要するにJavaからキックする時に

# java -cp ${catalina.base}/bin/tomcat-juli.jar:${catalina.home}/bin/bootstrap.jar

という風に代替juliがクラスパス上で優先されるようにしておけば良い。
<add addedDate=”2011/07/17″>追記:ちょいと訂正。ハードコードされているのは、恐らくtomcat-juli.jarではなくてorg.apache.juli.loggingの事と解釈できる。が、意味としては同じだ。代替juliを適切にクラスパスに入れてやれば良いのである。</add>
前述のtomcat7.shでは、${catalina.base}/bin/tomcat-juli.jarが見つかっても、クラスパス上でbootstrap.jarの後に追加しているため、bootstrap.jarのMANIFEST.MFの中の「同じディレクトリーのtomcat-juli.jar」を先にロードするので置き換えできていなかったのだ。なのでそこを書き換えてやればtomcat7.shも想定通り動くようになる。tomcat7.shはrcスクリプトなのでこれをリネームして/etc/init.d/tomcat6などとしてやれば/sbin/serviceやchkconfigで起動と停止の制御ができるようになる(Vine LinuxやRedhat Enterprice Linuxの場合)。

私はこれでtomcat-juli.jar→tomcat-juli-adapter.jar→log4j-over-slf4j-1.6.1.jar→slf4j-api-1.6.1.jar→logback-core-0.9.29.jarと紆余曲折を経てlogbackで全てのtomcatログを制御するようにしている。