Tuesday, November 24, 2009

java.util.logging over SLF4J

This year we have switched from log4j to SLF4J, using logback implementation of the "Simple Logging Facade" and jcl-over-slf4j and log4j-over-slf4j to deal with components that log using Jakarta Commons Logging and log4j respectively.
To have our collection complete, we thought it would be cool to include java.util.logging (JUL) - just in case some piece uses it.
Documentation says that there is a "jul-to-slf4j" module with a jul handler "that routes all incoming jul records to the SLF4j API". All you need is to call SLF4JBridgeHandler.install() once during application start-up.

The keyword here is "all". Once you register SLF4JBridgeHandler in your app, everything that gets logged via JUL in the entire JVM is logged in your app's log! I'd put the handler initialization into a servlet context listener and everything seemed to work fine - until I saw some puzzling messages in another web application that had the handler registered as well. And as long as I did not call uninstall, the messages multiplied with each application start as the number of handlers grew. You can imagine how perplexed we were since we though that the logged event really happens more than once (not that it only gets logged multiple times).

To call SLF4JBridgeHandler.uninstall() would not help anyway. A look at the source code shows that it removes all handlers that are instanceof SLF4JBridgeHandler. All from the entire JVM - for all web applications in our case.

To make the long story short, we have given up on "jul-to-slf4j". It can work only for a single application within a JVM and we cannot blame SLF4J here. There's something wrong with java.util.logging API all the way down.

No comments:

Post a Comment