logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Curt Arnold <carn...@apache.org>
Subject A new thread for log4j 2.0 discussion (Was Re: svn commit: r943816 [1/9] - in /logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers: ./ log4j12-api/ log4j12-api/src/ log4j12-api/src/main/ log4j12-api/src/main/java/ log4j12-api/src/main/java/org/ log4j12-api/src/main/java/org/apache/ log4j12-api/sr...)
Date Sat, 22 May 2010 02:44:56 GMT
Thought it might be best to leave the old thread behind, hope nobody minds.

On May 14, 2010, at 2:22 AM, Ralph Goers wrote:

> Thanks for trying it out. I hadn't actually built from the root - I've built the api
and core separately - so I'm glad you were able to fix those problems.
> I didn't want to commit code until I had the core of something that actually functioned.
I struggled for a couple of weeks over how to attack XMLConfiguration. I don't like the way
Logback does it, I didn't want to bring in baggage from a third party framework, JAXB isn't
a good fit either. In short, I wanted something that can be extended without needing to add
"rules" to the XML processor. See below for what I came up with.

I understand the desire to have something fleshed out enough so your thoughts have concrete
expression.  Easier to point to code than to try to express in verbiage your thoughts on how
everything is going to come together, but there are downsides and can be abused. 

> First, while I looked at Log4j and somewhat at Logback, most of the core code is completely
new. The exception to this is with the Converters for the PatternLayout. I took the EnhancedPatternLayout
and modified it.

I had totally forgotten that I called that EnhancedPatternLayout, so I wasn't sure if you
were talking about the extras version or the sandbox version.

> 1. I first created an API that had the features I was looking for. That is in log4j2-api.
While it supports logging a String or an Object it really uses a Message interface which is
valuable as it allows users to log self-describing objects in a convenient manner.

My thinking was the message interface would end up so minimal that might as well just use

> 2. I don't like the way Logback binds to the implementation. I used a technique I had
used in a previous logging framework and used a file to define the implementation class. In
theory, the API could be modified to support multiple logging implementation simultaneously,
although I have no plans to implement that.

Not something that I've thought about.

> 3. Logback suffers from a serious architectural problem that is rooted in Log4j. The
configured loggers are mixed with the loggers returned from the Logger factory. This makes
it impossible to reconfigure atomically. With Logback the reset method is called on the context
which essentially causes the system to be in an undefined state until the new configuration
is completed (log records that should be logged are lost). To solve this I used a design that
I again borrowed from my previous framework. The configuration is separated and on a reconfiguration
the new configuration will be created and then all the loggers will be updated to use it.
While there will be a period where some loggers are using the old configuration and some the
new there is never a point where loggers aren't configured at all.

I think that is along the line that I was thinking, basically there is an immutable configuration
state object that is swapped out as an atomic operation with notification to allocated loggers.

> 4. Similar to Logback I added support for Markers and global filters. In addition, filters
on Loggers are also supported. Unlike Logback, there is only a single Filter interface used
for global filters, logger filters and appender filters.

I've never had a clear description of the use cases behind Markers.  As far as I can gather,
it is a specialized case of a user supplied context.  At the core, I think it would fit into
a general user-supplied context object.  MDC and NDC would be part of the thread-supplied
context and there'd be a global context and a call-site context.  In the core, I'd expect
the context parameters to just be Object and let the layout level cast to specific known interfaces
as needed.  During the synchronous extraction phase, an immutable package would be assembled
for from log request parameters and the contexts based on the needs of the layout's formatting

> 5. The XMLConfiguration is extremely simple. All it does is read the XML and convert
the DOM structure to internal Node elements, which contain the node attributes, child node
references and placeholders for the real object when it is constructed. It uses the XML element
name to match to a Plugin, so instead of writing:
> <appender name="console" class="org.apache.log4j.ConsoleAppender">
>  <param name="Target" value="System.out"/>
>  <layout class="org.apache.log4j.PatternLayout">
>     <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
>  </layout>
> </appender>
> you write:
> <appenders>
>   <Console name="console" target="SYSTEM_OUT">
>     <PatternLayout>%-5p %c{1} - %m%n</PatternLayout>
>   </Console>
> </appenders>
> Note that it also would support
>   <Console>
>      <name>console</name>
>      <target>SYSTEM_OUT</target>
>     <PatternLayout>%-5p %c{1} - %m%n</PatternLayout>
>   </Console>
> if you prefer using elements over attributes.

It is something necessary, but hopefully configuration ends up something outside the core
using public methods to do its magic.

> 5. I implemented a "Plugin" concept. All core components use annotations to describe
their name and type. This is used by the XML configuration to determine the element names
that are used in the configuration file. 
> a) Plugins are used for Logger, Appenders, Filters, etc. The BaseConfiguration processes
the nodes created by XMLConfiguration and saves the resulting Objects as appropriate.
> b) PatternLayout uses plugins for the converters. To add a new converter an end user
just needs to create the class with the correct annotation and add the package name to the
XML configuration as an attribute.
> c) Configuration uses plugins to determine the Configuration implementation to use. The
XMLConfiguration and DefaultConfiguration will always be present, but a weight can be specified
to allow the new Configuration to take precedence. Again, simply placing the Configuration
class (with the appropriate annotations) in the classpath will cause it to be used. However,
if it is in a different package that package will have to be registered to be searched either
by calling a static method on the PluginManager or via a system property (which hasn't been
implemented yet).

Any thoughts on OSGi or other component frameworks?  Not now, maybe, never?

> 6. java.util.concurrent is used where appropriate. Accordingly, minimal locking takes
place. No lock is held while Appenders are called which is a serious bug in Log4j 1.x as it
causes deadlocks.
> 7, All internal components use the logger API for status reporting. A specific StatusLogger
provides the implementation. 
> 8. Layouts return a byte array. In Logback Ceki recently came up with the idea of using
encoders to allow binary data streams to be sent and received. While the requirement seems
valid it seemed awkward to wrap a Layout in an encoder.

I think there will likely need to be separate byte and character Layout-like interfaces. 
There are sometimes you are writing to a character-oriented destination like a database API
and other times to a byte-oriented destination like a file system or network socket.  You'd
like something like PatternLayout to be able to work in both instances (though it would need
to be paired with a character encoder for a byte-oriented destination).

The XMLLayout in log4j 1.2 suffers from this since it really should be byte-oriented.  At
the present, invalid XML can be generated if you do not use UTF-8 or UTF-16.

The Java serialization in the socket appender is effectively a byte-oriented layout and there
is no reason you should not be able to connect it to a file appender. 

> 9. Obviously, everything leverages Java 5 (and might possibly require Java 6 since that
is the JVM I've been using).
> The API is not compatible with log4j 1.x. My intention would be to create a compatible
API (to the degree possible) in a log4j12-api package.

I believe that we should try to do design the core so it is the best core and then later see
what, if any, needs to be tweaked.

> I've benchmarked this against Logback in both the SimplePerfTest and ThreadedPerfTest.
Logback is slightly faster, probably due to the separation of the configuration from the logger,
but the difference is about 1 or 2 hundredths of a second over a million log records that
don't pass the log level (i.e. no log records are written). 
> Although it is a decent amount of code this is meant to be just a starting point.  My
hope is that others, like yourself, will look at this and figure out how to improve on it.
And, of course, there are a bunch of Appenders, Filters, and other components that are completely
> Ralph

To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org

View raw message