Changes in log4j.properties are ignored, when running sl4fj under Tomcat
Lately, I run into this very subtle bug:
my logs were all visible, like intended and configured in
log4j.xml), when I fired up my web-application in development-mode under Jetty with
But if I installed the application on the production-server, which uses a Tomcat 7 servlet-container, no special logger-configuration where picked up from my configuration-file.
But – very strange – my configuration-file was not ignored completely.
The appender-configuration and the log-level from the root-logger where picked up from my configuration-file.
Only all special logger-configuration were ignored.
Here is my configuration, as it was when I run into the problem:
- Logging was done with slf4j
- Logs were written by log4j with the help of slf4j-log4j12
- Because I was using some legacy libraries, that were using other logging-frameworks, I had to include some bridges to be able to include the log-messages, that were logged through this frameworks in my log-files. I used: jcl-over-slf4j and log4j-over-slf4j.
Do not use sl4fj-log4j and log4j-over-slf4j together!
As said before: All worked as expected while developing under Jetty and in production under Tomcat, only special logger-confiugrations where ignored.
Because of that, it took me quiet a while and a lot of reading, to figure out, that this was not a configuration-issue, but a clash of libraries. The cause of this strange behaviour were the fact, that one must not use the log4j-binding slf4j-log4j12 and the log4j-bridge log4j-over-slf4j together.
This fact is quiet logically, because it should push all your logging-statements into an endless loop, where they are handed back and forth between sl4fj and log4j as stated in the sl4fj-documentation here. But if you see all your log-messages in development and in production only the configuration behaves strangley, this mistake is realy hard to figure out! So, I hope I can save you some time by dragging your attention to this.
Only the cause is hard to find. The solution is very simple: Just switch from log4j to logback.
There are some more good reasons, why you should do this anyway, over which you can learn more here.