I needed to implement a web application using Spring MVC that would be portable (as much as possible) across servlet containers and application servers. I used SLF4J for logging with Log4J as implementation and wanted the logging to be independent from the hosting container. We used Puppet to automate configuration management and deployment. Hence came the requirement to allow the (dev)op guys to configure the logging with an external file that is not embedded in the final WAR file.
Log4J offers the possibility to configure the logging via the
log4j.configuration system property (
-Dlog4j.configuration=path/to/the/config/file). The problem is when JBoss 7 starts up it sets the
log4j.defaultInitOverride system property to
"true" causing Log4J to skip its standard initialization process. Thus we need to find another way to enforce Log4J to use the configuration file set in the
A small modification to Spring’s
org.springframework.web.util.Log4jConfigListener can help us.
In the overridden
contextInitialized(..) method if the system property is set it is passed to the
Log4jConfigurer.initLogging(..) method to initialize Log4J with our external configuration file. In case of error or the property is
null Spring’s original behavior is used.
One more thing is necessary: declare the above listener in the web.xml:
If one plans to run more than one web application in the container and use different Log4J configuration for each of them then instead of using the
log4j.configuration property one should define separate system property for each application and use it to configure Log4J.
Note: To disable the container provided logging in JBoss for your web application you need to add a JBoss specific descriptor file to the WAR file: