The fact that
java.util.logging
made it into the JRE does not make it any better than it is, so there's a good reason to hide it behind a facade and never use it directly. But there is no reason for everyone to invent their own logging facades instead of simply using SLF4J.In my own applications, I always use SLF4J with Logback. Working with Tomcat, this means I'm getting an ugly mixture of log messages in different formats from my web application logging to System.out with Logback, and from Tomcat itself logging to System.err via JULI and java.util.logging, not to mention any third-party libraries contained in my application which use log4j, Apache Commons Logging or whatever.
There are two independent but similar approaches of replacing the official Tomcat JULI libraries by an SLF4J or Logback adapter: tomcat-slf4j and tomcat-slf-logback.
I've tried both, but in the end, I think it's easier to use nothing but the JUL-to-SLF4J bridge and other standard artifacts.
Setup for Tomcat
Get the following artifacts from Maven Central and copy them to
$CATALINA_HOME/bin
:- slf4j-api-1.7.2.jar
- jul-to-slf4j-1.7.2.jar
- logback-classic-1.0.6.jar
- logback-core-1.0.6.jar
Add the following line to
$CATALINA_HOME/conf/logging.properties
or replace the entire file contents byhandlers = org.slf4j.bridge.SLF4JBridgeHandler
Create a Logback configuration file in
$CATALINA_HOME/bin/logback-config/logback.xml
, e.g.<configuration debug="false"> <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <appender name="LOGFILE" class="ch.qos.logback.core.FileAppender"> <file>${catalina.base}/logs/tomcat.log</file> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="LOGFILE" /> </root> </configuration>
Create or edit
$CATALINA_HOME/bin/setenv.sh
:CLASSPATH=$CATALINA_HOME/bin/jul-to-slf4j-1.7.2.jar:\ $CATALINA_HOME/bin/slf4j-api-1.7.2.jar:\ $CATALINA_HOME/bin/logback-classic-1.0.6.jar:\ $CATALINA_HOME/bin/logback-core-1.0.6.jar:\ $CATALINA_HOME/bin/logback-config/
Now start Tomcat via
bin/catalina.sh run
and see it logging via Logback:
Setup for TomEE
The same procedure also works for TomEE if you delete the
slf4-api-*.jar
and slf4j-jdk14-*.jar
libraries that come with TomEE in CATALINA_HOME/lib
for the stand-alone distribution, or in CATALINA_HOME/webapps/tomee/lib
for the drop-in WAR.With this approach, all log messages are redirected, not only from Tomcat itself, but also from OpenWebBeans, OpenEJB and other components bundled with TomEE. The JULI replacements mentioned above only redirect Tomcat's own messages logged via JULI, since OpenWebBeans and OpenEJB have logging facades of their own.
8 comments:
I think you omitted the piece that needs to be added to logging.properties to activate the jul-slf4j bridge...
handlers = org.slf4j.bridge.SLF4JBridgeHandler
Thanks, you're absolutely right. I've added the missing bit to my post.
Anybody tried this with Groovy config file? This works fine with XML but I had few issues using Groovy.
Here is logback.groovy:
------------------------------------
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.FileAppender
import static ch.qos.logback.classic.Level.INFO
appender("STDOUT", ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"
}
}
appender("LOGFILE", FileAppender) {
file = "${catalina.base}/logs/tomcat.log"
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
}
}
root(INFO, ["STDOUT", "LOGFILE"])
----------------------------------
Marcin, I've never used a Groovy config file for logback myself, but I suppose it requires a Groovy runtime.
Did you add Groovy (and any transitive dependencies) to Tomcat's classpath, in addition to the SLF4J and Logback JARs?
yes, I did put all jars in classpath.
Thanks for the tutorial. I am currently facing a Handler error issue. Could you please let me know what I could be missing?
Here is the SO link http://stackoverflow.com/questions/16472801/handler-error-in-slf4jbridgehandler
Looks interesting, I'm going to give it a try.
Thanks for sharing
Thank you!
Post a Comment