I'm trying to configure Tomcat 8 to use Log4j2 for logging.
I've found this reference for Logging in Tomcat using Log4j. It provides a sample log4j.properties file that configures Log4j to match Tomcat's internal logging. Most of this looks pretty straightforward to convert for Log4j2, but the section at the end that maps loggers to appenders has me stumped:
# Configure which loggers log to which appenders
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost] = INFO, LOCALHOST
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager] =\
INFO, MANAGER
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager] =\
INFO, HOST-MANAGER
Has anyone converted this configuration to work with Log4j2? I've been working from the Log4j2 configuration documentation and have read through the Log4j2 Architecture page, but I haven't found much material on how to do this sort of container mapping in Log4j2.
I suppose I could do a separate configuration for each container, but I'd prefer to keep it in one place, as in the sample Log4j configuration.
After asking this question, I spent some more time with setting up log4j2, and this is the
log4j2.xml
file I came up with. It mimics the configuration
described in Logging in Tomcat using Log4j. It uses multiple loggers to route messages
to separate log files.
<?xml version="1.0" encoding="utf-8"?>
<Configuration status="info">
<Properties>
<Property name="logdir">${sys:catalina.base}/logs</Property>
<Property name="layout">%d [%t] %-5p %c- %m%n</Property>
</Properties>
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="${layout}"/>
</Console>
<RollingFile name="CATALINA"
fileName="${logdir}/catalina.log"
filePattern="${logdir}/catalina.%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${layout}"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<RollingFile name="LOCALHOST"
fileName="${logdir}/localhost.log"
filePattern="${logdir}/localhost.%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${layout}"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<RollingFile name="MANAGER"
fileName="${logdir}/manager.log"
filePattern="${logdir}/manager.%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${layout}"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<RollingFile name="HOST-MANAGER"
fileName="${logdir}/host-manager.log"
filePattern="${logdir}/host-manager.%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${layout}"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="CATALINA"/>
</Root>
<Logger name="org.apache.catalina.core.ContainerBase.[Catalina].[localhost]"
level="info" additivity="false">
<AppenderRef ref="LOCALHOST"/>
</Logger>
<Logger name="org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager]"
level="info" additivity="false">
<AppenderRef ref="MANAGER"/>
</Logger>
<Logger name="org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager]"
level="info" additivity="false">
<AppenderRef ref="HOST-MANAGER"/>
</Logger>
</Loggers>
</Configuration>
However, getting this to work properly required getting a bunch of other files configured correctly. The tomcat 7 internal logging with log4j2.xml posting from Paramita Banerjee was helpful with this.
This file goes in CATALINA_HOME/bin/
:
tomcat-juli.jar
If you're pulling this from the Maven repository, you'll get a file
named something like tomcat-extras-juli-8.0.15.jar
(the current
version when I wrote this). However, it needs to be renamed to
tomcat-juli.jar
– the Tomcat setup scripts use that name in
setting up the CLASSPATH.
These files go in CATALINA_HOME/lib/
:
commons-logging-1.2.jar
log4j-1.2-api-2.1.jar
log4j-api-2.1.jar
log4j-core-2.1.jar
log4j-jcl-2.1.jar
log4j-jul-2.1.jar
log4j-web-2.1.jar
tomcat-juli-adapters-8.0.15.jar
log4j-web-2.1.jar
may not be needed here (it may just need to be deployed with your web application) – its use is described in
Using Log4j 2 in Web Applications.
log4j-1.2-api-2.1.jar
is needed only if you have applications that use
the older log4j 1.2 interface.
In CATALINA_BASE/conf
, I disabled logging.properties
.
I used the following setenv.sh
script to define the CLASSPATH
and
LOGGING_MANAGER
environment variables correctly for Tomcat. It goes in either
CATALINA_BASE/bin
or into CATALINA_HOME/bin
. (I put it in
CATALINA_HOME
/bin.) It is executed by Tomcat's startup scripts if it's
present. You might prefer something simpler, but this is in keeping with
the style of the startup scripts.
LOG4J_JARS="log4j-core-2.1.jar log4j-api-2.1.jar log4j-jul-2.1.jar"
# make log4j2.xml available
if [ ! -z "$CLASSPATH" ] ; then CLASSPATH="$CLASSPATH": ; fi
CLASSPATH="$CLASSPATH""$CATALINA_BASE"/lib
# Add log4j2 jar files to CLASSPATH
for jar in $LOG4J_JARS ; do
if [ -r "$CATALINA_HOME"/lib/"$jar" ] ; then
CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/lib/"$jar"
else
echo "Cannot find $CATALINA_HOME/lib/$jar"
echo "This file is needed to properly configure log4j2 for this program"
exit 1
fi
done
# use the logging manager from log4j-jul
LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager"
As Nick mentioned in his response, there's also the output to the access log. I haven't tried to do anything with that, either.
I hope others find this useful. In retrospect, it seems pretty straightforward. However, there are a lot of parts that have to be “just right” for it to work, and that was a challenge (at least for a newbie).
I followed the reference for Logging in Tomcat using Log4j and added tomcat-juli.jar to the bin dir and I also added tomcat-juli-adapters.jar to the lib dir. Afterwards i added the log4j-api-2.1.jar, log4j-core-2.1.jar and log4j-1.2-api-2.1.jar to the lib dir.
After that I added log4j2.xml to the lib dir. I kept the configuration fairly simple using a time and size based rolling configuration that zips the archived logs:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="catalina" packages="">
<Appenders>
<RollingRandomAccessFile name="catalina"
fileName="${sys:catalina.base}/logs/catalina.log"
filePattern="${sys:catalina.base}/logs/catalina/$${date:yyyy-MM}/catalina-%d{yyyy-MM-dd}-%i.log.zip">
<PatternLayout>
<Pattern>%d{MMM d, yyyy HH:mm:ss}: %5p (%F:%L) - %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="250 MB" />
</Policies>
<DefaultRolloverStrategy max="100" />
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<!-- default loglevel for emaxx code -->
<logger name="org.apache.catalina" level="info">
<appender-ref ref="catalina" />
</logger>
<Root level="info">
<appender-ref ref="catalina" />
</Root>
</Loggers>
</Configuration>
This way you'll get all logging in the catalina.log.
I'm still working on getting the accessLog to do the same.
EDIT: I found this site. this way you can direct access logging to the catalina.log. (I couldn't get it to log to it's own appender)
I didn't worry about the logging for manager and host manager, since we don't have them in production environments, but they might just log to the catalina.log too. I haven't tested it.
This was tested on tomcat-7.0.42, it should work in tomcat8 too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With