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

Why are you relying on the StdErrLog fallback logging?

By default, Jetty uses Slf4j, and if that doesn't work, falls back to StdErrLog.
The declared default:
https://github.com/eclipse/jetty.project/blob/jetty-9.1.0.v20131115/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java#L128

The instantiation:
https://github.com/eclipse/jetty.project/blob/jetty-9.1.0.v20131115/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java#L172

And fallback:
https://github.com/eclipse/jetty.project/blob/jetty-9.1.0.v20131115/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java#L179

The JavaUtilLog suggestions does work.
Even created an example to show you. :)

https://github.com/jetty-project/embedded-jetty-logging-examples

The basic approach can be found in the "jul-logging" example project.
Test case:
https://github.com/jetty-project/embedded-jetty-logging-examples/blob/master/jul-logging/src/test/java/org/eclipse/jetty/demo/AppTest.java#L62-L82

If you want to capture any of the following (even at the same time) in your test case, you can look at the "mixed-logging" example.
  * commons-logging
  * Jetty Logging
  * java.util.logging
  * log4j
  * slf4j

The mixed-logging example has 5 servlets, each using a different logging technique:
https://github.com/jetty-project/embedded-jetty-logging-examples/tree/master/mixed-logging/src/main/java/org/eclipse/jetty/demo

The TestCase for mixed-logging calls each servlet...
https://github.com/jetty-project/embedded-jetty-logging-examples/blob/master/mixed-logging/src/test/java/org/eclipse/jetty/demo/AppTest.java#L90-L101
... while a capturing logger is in place ...
https://github.com/jetty-project/embedded-jetty-logging-examples/blob/master/mixed-logging/src/test/java/org/eclipse/jetty/demo/AppTest.java#L78
... and then asserts that those events occurred.
https://github.com/jetty-project/embedded-jetty-logging-examples/blob/master/mixed-logging/src/test/java/org/eclipse/jetty/demo/AppTest.java#L103-L107





--
Joakim Erdfelt <joakim@xxxxxxxxxxx>
Expert advice, services and support from from the Jetty & CometD experts


On Tue, Nov 26, 2013 at 8:05 AM, Lothar Kimmeringer <job@xxxxxxxxxxxxxx> wrote:
Am 26.11.2013 15:24, schrieb Joakim Erdfelt:
> Inline...

not sure what that means.

First of all: I'm not trying to start a flamewar here. I just
try to understand a decision that was made between Jetty 7.0
and Jetty 7.6

>      - 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 ...)

All of them are used in one way or another in libraries I use for
my application. All of them are redirected to a server-log and all
of them happily do that except Jetty when I switched from 7.0 to 7.6
and 9.0.

>      - 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?

I'm happy with the concept in 7.0. I have to check, but the difference
between 7.0 and 7.6 is the added static and the need to call Log.getLog.log...
instead of Log.log. You already had the features you listed below.

> Jetty 6 had no named logging, no ability to filter, and it was hostile
> towards other existing logging frameworks.

I was never talking about Jetty 6 but Jetty 7.

>      - 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)

You can't say that since classes are loaded e.g. when defining a
CharsetProvider (via META-INF/services). I might find more
examples (JavaMail Mailcap is a good candidate for that), so
you can't be 100% sure that simply adding a Jar to your Classpath
doesn't change the behavior of your logging.

>     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.

There is a logfile but in addition to that we log into the event-log.

> Only severe errors at the Service layer itself would show up in
> the WIndows Event Log.

Just looking into the log shows that the reality is different since
there are a couple of purely informational entries. But I
agree that there shouldn't be any debug-messages in that log which
is the reason why I don't want Jetty-messages in there.

> Also, you apparently have a much more demanding need of Jetty's
> logging than what StdErrLog is for.

No, I simply want to keep these messages from being outputted
on STDOUT and STDERR.

> Switch, use org.eclipse.jetty.util.log.JavaUtilLog

I already use that class in the application itself when starting.
The point is that setting it programmatically simply has no effect
if the Jetty-classes are already loaded. I found a workaround (with
the above mentioned danger of a jar that might recreate the problem)
but that workaround doesn't work with JUnit-classes that need to
import the Jetty-classes in question leading to the described problem.

>     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.

During tests I want to see the logs on STDOUT/STDERR in addition to
the adding to the internal list (I call super.log for that), so
your suggestion doesn't work. And - again - all that has simply no
effect at all if the Jetty-class is loaded by the classloader because
I can't set my own implementation anymore. All the classes being
loaded by the ClassLoader already have their StdErrLog-instance
being set by the static-constructor. Only classes that are loaded
after the call of Log.setLogger() get the new one, so you end up
with some messages going to STDERR and some that are going to the file.


Regards, Lothar
_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/jetty-users


Back to the top