On Thu, 16 Aug 2001, Ceki Gülcü wrote:

> We do indeed create a fresh LoggingEvent every time a positive
> decision is made to log.
>
> Note that the LoggingEvent will not be created if logging is turned of
> entirely or if it is disabled for the category and priority associated
> with the log request.
>
> On the other hand, the 1-2 microseconds performance overhead involved
> in the creation of a fresh LoggingEvent is dwarfed by the time it
> takes to format the output and write it to the output device
> (e.g. disk, console, syslog, wire..).

> Just as importantly, log4j components can be called from multiple
> threads. As such, we now have to start worrying about pooling
> LoggingEvent instances, worry about their synchronization etc. As I
> see it, the 0.1% performance gain is not worth the effort. Or is it?

It's 0.1% or 1-2 microseconds if you are in a client environment doing
some normal stuff.

In a server environment you have 80 threads serving 200 requests per
second, each request generating at least 1 log message ( the access log ),
maybe more. And the GC time can go to 3-4 seconds of "frozen server".

And it's not only the LogEvent object - there are also tons of strings
that are allocated.

Again, it may be ok for a client application, but it doesn't scale.

As of the time to format/write to disk: yes, right now formating is string
based and likely to be inefficient, but both of them happen ( or should )
on separate threads, with lower priority, etc. And it's quite possible to
format the LogEvent object ( ignoring the existing interfaces ) without
generating garbage. So both of them can be optimized without changing the
API that is exposed to the user, I'm not worried about that.

I may sound like a garbage-obsessed person, but so far my experience is
that this is the most important factor in a server performance.
The most important change between 3.0 and 3.3 from performance point of
view is eliminating garbage, and I think the result is visible.

This is an API issue - I don't care if log4j default implementation
recycles or not - I just want to make sure that the API provides a way to
allow a zero-garbage use.

Try a simple servlet that does 5 logs. Check it's response time. Then
try again with 200 requests per second. Check the response time again.
Remove the log statements and try again both experiments.

> >3. Security. If log4j is included in the main classpath ( i.e. tomcat/lib,
> >etc ), _all_ webapps have access to _all_ loggers. That means
> >untrusted_app1 can see and modify logging for untrusted_app2 or for
> >trusted_app3.
>
> That's a very interesting problem. One solution is to have different
> webapps use different hierarchies. This feature was actually
> developed for Tomcat.

??? The current code doesn't seem to have such a thing. There are static
fields, static methods, and it's quite easy to mess.

Again, back to the API - it's not a matter of beeing able to set tomcat so
that loggers are separated, but a matter of beeing able to guarantee that
the API doesn't allow one app to mess with another app's logger.

Separating the API from implementation and from examples/experiments/test
is extremely important.

As an additional note, in a sandboxed environment log4j will need special
permissions. You can't get away without that, apps can only write in the
work dir ( which can be removed ). So logging most be dealt with at the
server level, if you run in a server, at least the permission configuration
( or your apps will not run in the sandbox ).

Costin

Reply via email to