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