Hello Juergen,
Thank you for this post which explains the advantages as well as the
technically delicate points involved in replacing jul's LogManager. At
present time my todo list very long and as such I am unlikely to visit
this issue in the near future, this contribution is not going to get
the attention it requires.
However, creating a bug report for this contribution would be a first
and minimal step to ensure that it is not completely forgotten.
In addition to the bug report we could try something new. Why don't
you create a fork of slf4j on github, add your version of jul-to-slf4j
(perhaps rename it jul-over-slf4j) and have other people try it. We
could then add a link from the SLF4J web-site to your fork with a
brief description encouraging people to try and experiment with your
idea. I suspect others would be interested enough to try your
fork. BTW, Per Lindberg floated a related idea only 2 weeks ago. There
must be a least some demand for this feature.
Does that sound at least a tiny bit encouraging or realistic?
On 05/03/2010 2:31 PM, [email protected] wrote:
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/
_______________________________________________
slf4j-dev mailing list
[email protected]
http://qos.ch/mailman/listinfo/slf4j-dev
_______________________________________________
slf4j-dev mailing list
[email protected]
http://qos.ch/mailman/listinfo/slf4j-dev