XML形式のlog4j設定(log4j.xml)をGrailsで使用する
Grailsではロギングの設定がConfig.groovyで設定できますが、なんらかの理由でXML形式の設定(log4j.xml)で行ないたいことがあるかもしれません。しかし、その場合log4j.xmlをどこに置くか、という問題があり得ます。
この問題を説明します。まずGrailsでlog4jのXML設定を使用するには、springの設定ファイルresouces.groovyで、以下のようにlog4jConfigurerを設定します。
GRAILS_PROJ/grails-app/conf/spring/resources.groovy
beans = { log4jConfigurer(org.springframework.beans.factory.config.MethodInvokingFactoryBean){ targetClass = "org.springframework.util.Log4jConfigurer" targetMethod = "initLogging" // arguments = "grails-app/conf/log4j.xml" // ★1 arguments = "classpath:log4j.xml" // ★2 } }
問題は、★1のようにカレントディレクトリ相対で指定すると、warにしてtomcatなどにデプロイした状態では、tomcatが走行しているときのカレントディレクトリ($CATARINA_BASE)からの相対になり、読み取ることができないということです。だからといって、絶対指定も一般にはできないでしょう。
この解決策ですが、まずlog4j.xmlはgrails-app/conf配下に置いた上で、(★2)のようにxmlがclasspath配下にあると指定します。run-appの際には、grails-app/confはクラスパスに入っていますのでこれで動作します。
ただし、warにしたときには、conf配下は特にはクラスパスにはいっているわけではないので(Config.groovyなどはコンパイルされてclasses配下に移動している)、warの作成時にgrails-app/conf/log4j.xmlを適切なclasspathの通っているところ、たとえば以下ではWAR中の$WEB-INF/classes/配下にコピーするように、BuildConfigに以下の設定を追加します。
GRAILS_PROJ/grails-app/conf/BuildConfig.groovyに追加。
grails.war.resources = { stagingDir, args -> println "$stagingDir, $args" copy(file: "grails-app/conf/log4j.xml", todir: "${stagingDir}/WEB-INF/classes/") }
なおログファイルをそもそもどこに置くか、という設定はlog4j.xmlに記入しておく必要があります。XML設定の場合、grailsのConfig.groovyで設定するように、developmentのときとprod/testのときに場所を切り替えたりということはたぶんできないので、適当に絶対パスで指定することになるでしょう。
ちなみに、Wiki - Log4j XML Pluginというプラグインもあり、XMLでの設定に対応する、markupbuilderっぽい記法で設定することができるようです。これを使えば、もっとうまくいくのかもしれませんが試してません。