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


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


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


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

Reply via email to