Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Why are Loggers static members in classes


On Tue, Nov 26, 2013 at 2:44 AM, Lothar Kimmeringer <job@xxxxxxxxxxxxxx> wrote:
Am 25.11.2013 17:39, schrieb Joakim Erdfelt:
> Why are you using logging event messages?
> LifeCycle events (like in your example) can be monitored using
> a LifeCycle.Listener.

Features like LifeCycle events are not the point since AbstractLifeCycle
was just an example. Another one is org.eclipse.jetty.server.Server.
This is a class that can be expected to be instantiated only once
(or twice in my specific application) during the whole runtime of
the server, so the argument that it's avoiding excessive garbage
collection is even less convincing. Currently it more looks like
an OSI-10-level-reason than a technical one.

I counter that most reasons you have for wanting to manipulate logging in your tests are likely invalid, and there are better ways of accomplishing your end goals in your stated test cases.
Strictly speaking this is a premature optimization (or are there
actual numbers showing that an existing bottle neck was fixed this
way?) coming with some implications for real life applications:

Logging events are not instance level events, they are events about a particular point in code.
Instance level logging, or context is handled via various context logging techniques such as MDC/NDC.

 - Setting a logger programmatically only works if it happens before
   any classloading of Jetty-classes (except the Log-class of course).

Just like all other logging frameworks out there. (java.util.logging, jakarta / aka commons-logging, log4j 1.2 and 2.0, slf4j, logback, etc ...)
 - Changing the type of logger during runtime isn't possible anymore

So you much prefer the 1 instance of Logger and Log that Jetty 6 had? Huh?
Jetty 6 had no named logging, no ability to filter, and it was hostile towards other existing logging frameworks.
 - The success of setting the logger is non-deterministic. If you add
   a jar to your classpath that lead to the loading of Jetty-classes
   you lose again.

Simply adding a jar to a classpath does not load that class into your classloader (causing the Log/Logger to instantiate)
If you have an application that runs as Windows Service all output on
STDOUT/STDERR will be added to the Windows Event Log. Every single line
is a new entry. So if you don't get the logger changed successfully and
activate debugging, your Windows Event Log will explode while you're
wondering, why your own server-log still only contains the log-messages
of your own classes (if there are any).

If you properly setup your Windows Service using Apache Procrun, or Tanuki Java Service Wrapper, or even YAJSW then you'll have a log files, not Windows Events.
Only severe errors at the Service layer itself would show up in the WIndows Event Log.

Also, you apparently have a much more demanding need of Jetty's logging than what StdErrLog is for.
Switch, use org.eclipse.jetty.util.log.JavaUtilLog or org.eclipse.jetty.util.log.Slf4jLog and use those system's runtime abilities.

That's one of the reasons why I test the log-messages (instead of e.g.
get LifeCycle-events). I want to make sure that the setting of the
logger works (it already was quite some work in the past, so I test
that now). The example in my last mail was only intended to show the
impossibility to set the logger in a reasonable way, there are others
that fail as well for the same reason.

If you are just testing logging ... 

Don't extend / override StdErrLog.
Say, for example, a MyOccasionalCapturingLogger implements Logger.
Have it always display events.
But have the ability to start/stop/reset capturing of events for those testcases that you want to know events from.

Or, a better technique, use org.eclipse.jetty.util.log.JavaUtilLog always, then just add/remove a CapturingHandler to java.util.logging.Logger level that you want to know about (be it either the root/global handler or a specific named logger), then remove it in your finally block on your testcase.

Back to the top