logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ralph Goers <ralph.go...@dslextreme.com>
Subject Re: 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 04:15:01 GMT

On May 21, 2010, at 7:44 PM, Curt Arnold wrote:

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

Actually, I had no idea how it would come together. I just had some vague idea of what I wanted
to do and watched what popped out. 

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

I don't think so. For example, take a look at StructuredDataMessage and LocalizedMessage.
Those allow you to do some interesting things. The idea is that it is easy for users to extend
without having to muck with the internals. Ceki handled this by creating logback-classis,
logback-access and logback-audit. That seemed to me to be a very heavyweight approach to accomplish
this.

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

Probably not. It just occurred to me that it is possible as I was implementing it but decided
it wasn't an itch I needed to scratch at the moment.

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

Exactly.

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

I think I'd need to see code to get what you are driving at.  In the code I checked in it
does have the MDC & NDC and does have a global context, although I haven't added variables
to it yet. It also has the configuration which can also have variables, but probably for a
different purpose. I don't know what you mean by "call-site context".  

The value of Markers is that they are fast and easy to filter on. I use them for Entry and
Exit so that you can easily filter them out (admittedly this can also be done via the TRACE
level) as well as catching and throwing. In addition, I also use a Marker to identify audit
events. Anything with that Marker will always be logged.


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

The API doesn't have any visibility to the configuration. In this implementation BaseConfiguration
really does all the work. Any number of implementations could extend it to support various
ways of expressing the configuration.

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

OSGi has to be supported. I would call myself an OSGi novice. Hopefully, this is an area where
others with more experience can provide ideas and code.

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

That is pretty much why I made the Layout return the byte array. Alls the Converters in the
PatternLayout manipulate Strings. The resulting String is converted to a byte array at the
last moment.

> 
> 
>> 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 checked in the log4j 1.x API the other day. It isn't completely compatible as the underlying
foundation doesn't have a Hierarchy or Repository. And it may not be compatible operationally.
But again, it is a place to start.


Ralph



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


Mime
View raw message