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: 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 Fri, 14 May 2010 07:22:14 GMT
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.

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.

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

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

On May 13, 2010, at 10:17 PM, Curt Arnold wrote:

> log4j2-api/pom.xml has a stray </build> (see patch following).  Also, the master
pom in BRANCH_2_0_EXPERIMENTAL/rgoers expects log4j2-docs to be in the same directory, when
it is currently located one directory closer to root.  After those changes, I was able to
run "mvn test"/
> 
> I haven't had a chance to review the rest of the commit, but it seems like a substantial
amount of work that was done in isolation.  While things are still fresh, can you walk through
the whats in this thing and the decisions that you made.
> 
> 
> Index: log4j12-api/pom.xml
> ===================================================================
> --- log4j12-api/pom.xml	(revision 944109)
> +++ log4j12-api/pom.xml	(working copy)
> @@ -28,7 +28,6 @@
>   <packaging>jar</packaging>
>   <name>Log4J Compatibility API</name>
>   <description>The Log4J Compatibility API</description>
> -</build>
>   <dependencies>
>     <dependency>
>       <groupId>junit</groupId>
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-dev-help@logging.apache.org
> 


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