[slf4j-dev] jul-to-slf4j bridge via LogManager, prototype

work_registries at web.de work_registries at web.de
Fri Mar 5 14:31:15 CET 2010


First, my apoligies for using an alias email, its Juergen, not Max :)
Second, having subscribed in digest mode, I found your reply in the archive and wanted to answer, but breaking the discussion chain.

The implementation tries to improvement shortcomings of jul-to-slf4j bridge mentioned in http://www.slf4j.org/legacy.html#jul-to-slf4j:
* java.util.logging.Logger being a core java package class, slf4j bridging by providing replacements for other logging classes like log4j.Logger does not work.
* SLF4JBridgeHandler being a handler implies that it's still necessary to configure jul Loggers in parallel to the slf4j backend or at least to forward every log event to slf4j handler
* jul-to-slf4j translation therefore has - as mentioned - negative performance impact

The idea is to have the jul Logger class replaced (similar to other bridges) but not by providing a new java.util.logging.Logger, but by providing a new slf4j LogManager that creates java.util.logging.Logger based loggers. You gain the same advantages as e.g. by providing a log4j.Logger replacement.

Based on sun jvm configuration options
for LogManager as mentioned in http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/LogManager.html:
-Djava.util.logging.manager=org.slf4j.bridge.LogManager
adding jul-to-slf4j bridge classes (LogManager, Logger) to bootclasspath via
-Xbootclasspath/a:jul-to-slf4j-boot.jar
(or putting it into /ext dir?)

Issues:
* Properly translating all public/protected jul Logger methods to corresponding slf4j Logger methods is not completely/properly done in the prototype implementation I provided.
* Allowing a slf4j LogManager configuration (similar to jul LogManager being configured via logging.properties) e.g. for providing a mapping for jul Level to slf4j Levels, is also coded and not configurable.

For special consideration is the fact that other java core classes make use of jul Logger immediately after jvm startup (at least in my case running jboss-4.3.2.GA). So either slf4j + backend is provided as a bootclasspath as well or - as I tried to do in my prototype - slf4j jul Logger replacement tries to create slf4j Loggers - I'm using Thread ContextClassLoader for this - and if successful - permamently (possible memory leak?) wires slf4j jul Logger to slf4j Logger. Or if unsuccessful (as long as slf4j Loggers + backend are not in Classpath) simply calls its superclass jul Logger methods. In that case it might still be necessary for slf4j LogManager to call jul LogManager configuration/methods to allow for jul logging configuration being in effect at early system startup until slf4j replacement kicks in.
* slf4j jul Logger must be usable without other slf4j class references -> sadly reflection necessary, but still better performance than with BridgeHandler?
* repeatedly tries to create slf4j logger on every method invocation until wired -> expensive repetitive checks for slf4j Logger in classpath, but only until slf4j available

Hope I could explain my thoughts on that matter and that it - if considered - proves to be more of an improvement than a complication.

gr, Juergen

In reply to:

Hello Max,

Thank you for this contribution. Perhaps a stupid question but what is
the purpose of replacing jul's LogManager and creating a Logger class
extending java.util.logging.Logger? You say that you were unsatisfied
with the existing jul-to-slf4j adapter, how so and how does your
implementation improve things?


On 04/03/2010 6:36 AM, Max Mustermann wrote:
> Hi!
>
> Being unsatisfied with existing jul-to-slf4j adapter I tried to search
> for a better way to bridge jul to slf4j
>
> Attached you find a prototype implementation based on the following
> concepts:
>
> * A jul LogManager extending java.util.logging.LogManager creating newly
> introduced org.slf4j.bridge.Logger subclassed from java.util.logging.Logger
> * setting LogManager via jvm property:
> -Djava.util.logging.manager=org.slf4j.bridge.LogManager
> * adding LogManager / Logger to bootclasspath:
> -Xbootclasspath/a:path/to/jul-to-slf4j.jar
> * LogManager has mapping for jul logging call source Level to target jul
> Level, mapping for target jul Level to slf4j log methods: e.g. source
> Level.FINEST -> target Level.FINE, target Level.FINE -> slf4j trace
> * LogManager mapping hardcoded but possibly configurable by
> adapting/improving readConfiguration() / readConfiguration(InputStream)
> * A org.slf4j.bridge.Logger extending java.util.logging.Logger that has
> a very simple lazy slf4j logger lookup + forwarding of most methods to
> slf4j methods. NEEDS IMPROVEMENT: logrb methods, entering, exiting,
> throwing, etc.
> * As org.slf4j.bridge.Logger is probably instantiated very early in
> system startup (replacing sun internally used Logger instances as well)
> it cannot be assumed that slf4j is already in classpath. So I have done
> a lazy lookup of Slf4j Logger via reflection. If found, it keeps a
> reference (possible memory leak?), if not, it falls back to
> java.util.logging.Logger super calls. The slf4j method invokations are
> therefore via reflection as well. Possible performance improvments by
> caching Method elements, maybe use java.lang.reflect.Proxy, bytecode
> rewriting, ... ?
>
>
> Tried it with jboss-4.2.3.GA and it seemed to work.
>
> greetings, J?rgen
___________________________________________________________
WEB.DE DSL: Internet, Telefon und Entertainment für nur 19,99 EUR/mtl.!
http://produkte.web.de/go/02/


More information about the slf4j-dev mailing list