PROBLEM
Most of the time, we set the Log4j’s log levels to something lower (debug
or info
) during our local development. Once it is ready for production, we normally set the Log4j’s log levels to something higher (warn
or even error
) to prevent meaningless information from flooding the server log.
One way to do this is to manually adjust the log level(s) in log4.xml
during our local development, for example:-
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<!-- This appender logs to the console -->
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%c{1}] [%M:%L] - %m%n"/>
</layout>
</appender>
<!-- Set "debug" log level for project code -->
<logger name="com.choonchernlim.myproject">
<level value="debug"/>
</logger>
<!-- Set "info" log level for Spring framework -->
<logger name="org.springframework">
<level value="info"/>
</logger>
<!-- Set "debug" log level for Hibernate framework -->
<logger name="org.hibernate">
<level value="debug"/>
</logger>
<root>
<!-- The default log level is "warn" -->
<priority value="warn"/>
<appender-ref ref="consoleAppender"/>
</root>
</log4j:configuration>
Once we are ready for production, we will manually change the package specific log levels back to warn
or comment them out, for example:-
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<!-- this appender logs to the console -->
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%c{1}] [%M:%L] - %m%n"/>
</layout>
</appender>
<!-- Comment out package specific log levels
<logger name="com.choonchernlim.myproject">
<level value="debug"/>
</logger>
<logger name="org.springframework">
<level value="info"/>
</logger>
<logger name="org.hibernate">
<level value="debug"/>
</logger>
-->
<root>
<!-- The default log level is "warn" -->
<priority value="warn"/>
<appender-ref ref="consoleAppender"/>
</root>
</log4j:configuration>
The problem with this approach is I always forget to make necessary changes in log4j.xml
when I’m ready to package my project to be deployed in production.
SOLUTION
The solution that I come up with is rather simple. We will have two Log4j XML files under src/main/resources
:-
By default, assuming there’s no further Log4j configuration, log4j.xml
will always get picked up by Log4j due to the default filename and its location. log4j-dev.xml
will always be ignored by Log4j.
To ensure our local development picks up the configuration from log4j-dev.xml
, we will need to make a minor tweak to the Jetty configuration in pom.xml
:-
<project ...>
...
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.8.v20121106</version>
<configuration>
<systemProperties>
<!--
When Jetty runs, "log4j-dev.xml" will be used instead of
"log4j.xml" because the latter is reserved for production
usage.
-->
<systemProperty>
<name>log4j.configuration</name>
<value>log4j-dev.xml</value>
</systemProperty>
</systemProperties>
...
</configuration>
<dependencies>
...
</dependencies>
</plugin>
</plugins>
</build>
</project>
This way, when we run our local development on Jetty, log4j-dev.xml
will be used. When we deploy the project in production, log4j.xml
will be used instead.