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-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org

Reply via email to