BT

LOGBack: Evolving Java Logging

by Geoffrey Wiseman on Aug 22, 2007 |

Ceki Gülcü is well known in the world of Java logging. He founded Log4J, the original Java logging framework that has been quite popular despite the inclusion of logging within the JRE. He then set about to replace Jakarta commons-logging with SLF4J, a 'simple logging facade' for Java.

During the past year, Ceki has been working on a new project, LOGBack, "the reliable, generic, fast and flexible logging framework for Java." Since the 0.1 alpha release just over a year ago, LOGBack has been gaining momentum. With a 1.0 release just around the corner and some positive reviews from adopters, this may be the right time to take a look at LOGBack, and see if it can work for you.

Xavier Hanin comments on his experience with LOGBack:

I've been using logback for a few months now, and I'm impressed!

With excellent documentation and support, neat logging features, blazing performance and an innovating eclipse plugin, I've finally found a good replacement for the good old log4j.

Rob Willams adds:

Oh, also, we did take the plunge and have been using LogBack. Love it. Zero hassle switching, absolutely love the replace syntax.

The replace syntax to which he's referring allows LOGBack to accept many complex logging statements without an enclosing check of the logging level and with negligible performance implications. Where one might write something like this in Log4J:

if( logger.isDebugEnabled() ) {
logger.debug( "User with account " +
user.getAccount() + " failed authentication; " +
"supplied crypted password " + user.crypt(password) +
" does not match." );
}

The equivalent statement in LOGBack could be:

logger.debug( "User with account {} failed authentication; " +
"supplied crypted password {} does not match.",
user.getAccount(), user.crypt(password) );

This defers the cost of message assembly until LOGBack has ascertained whether or not this message will be viewed. It doesn't defer the cost of retrieving expensive parameters, such as the password crypting in the above example.

LOGBack also makes claims of greater performance:

Certain critical operations, for instance determining whether a log statement should be logged or not, has been significantly improved. This operation takes about 3 nanoseconds in logback versus 30 nanoseconds in log4j. Logback also creates loggers faster : 13 microseconds instead versus 23 microseconds for log4j. More importantly, it fetches an existing logger in 94 nanoseconds versus 2234 nanoseconds for log4j, a 23 fold improvement. The improvement over JUL is also far from insignificant.

LOGBack has integration feature as well, with an Eclipse plugin and a JMX configurator bean.

InfoQ spoke with Ceki about LOGBack, starting with the question many of you will have considered: Why develop another logging framework rather than working towards getting these changes made in Log4J?

I believed at the time (and still do to some extent) that it was easier to innovate outside Apache Logging Services project than within it. Please don't get me wrong, I think very highly of the Apache Software Foundation, it is a unique and in many ways wonderful organization. Who knows, some day SLF4J and logback, perhaps after establishing themselves as the new de facto logging standards, may well be merged back into the Apache.

On the adoption of SLF4J:

Now that several major-league projects, such as Hibernate, Jetty, Spring-OSGI and Wicket have migrated to the SLF4J API, I can honestly say that SLF4J is gaining considerable traction. SLF4J is popping up in all sorts of places despite that fact that the terrain is already occupied by Jakarta Commons Logging (JCL), a very widely-used library, basking under the warm glow of the Apache brand. Considering that it started off at a disadvantage, SLF4J is doing better than initially expected.

When asked to compare LOGBack's free documentation with the Log4J approach of limited free documentation and extensive commercial documentation:

As you point out, log4j offers only limited free documentation, with the fully-fledged documentation available for a fee. In logback, we have adopted a different approach where all documentation is placed on our project site in plain sight, accessible to all gratuitously, providing an additional reason for Java developers to switch to logback. Besides, the market share of logback is an order of magnitude smaller than log4j's. It would make no economic sense to sell documentation for logback.

As for the long term economic sustainability of the project, we have developed a product loosely related to logback. It will be revealed in the coming weeks. Our long term plan calls for logback to be developed as a gimmicks-free and collaborative open-source project. By collaborative, I mean open for contribution from developers outside the current group of developers.

Describing what's still necessary for a 1.0 release:

For to the upcoming 1.0 release, most of the big pieces are already there. We need to fix a number of bugs but mostly we need to improve documentation, do more testing, rise and repeat. Did I mention better documentation?

There is still much to be done in the area of logging, perhaps enough to last several lifetimes. We've got a relatively clear vision of the road ahead and hope to pave some of the way.

When asked what reasons developers might find compelling to switch to LOGBack:

There is no definitive answer. Some users may find performance a compelling reason to switch, while others are satisfied with what log4j has to offer. Although I and the rest of the logback developers are trying hard to give users compelling reasons, many of us are just happy to work on a software project with emphasis on quality. We get to eat our own dog food, acquiring valuable software development skills in the process — that's not such a bad deal by today's standards. Considering that the logback project picks up where the log4j project leaves off, as long as we continue providing improvements to logback at a sustained rate, we believe that Java developers will adopt the SLF4J/logback combination in increasing numbers.

Because SLF4J and LOGBack can bridge competing APIs, developers can replace Log4J (using log4j-bridge.jar) and Jakarta Commons-Logging (using jcl104-over-slf4j.jar) with LOGBack in their own projects, preventing them from having to configure two or more logging frameworks in one project just to use LOGBack.

For more information on LOGBack and SLF4J, read Ceki's presentation on ten reasons to switch to LOGBack, or stay tuned to InfoQ's Java community.

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Why not just add Formatter support to log4j? by Thom Nichols

Would it be so hard to add Formatter-style methods to log4j?

Closures and Logging by Geoffrey Wiseman

In the vein of not-doing-expensive-operations-for-logging-not-logged, I was pleased to discover that languages with closures/blocks have employed that in order to achieve the same result.

e.g.:

logger.debug do
"User " + user + " with account " +
user.getAccount() + " failed authentication; " +
"supplied crypted password " + user.crypt(password) +
" does not match."
end

Re: Closures and Logging by Martin Grigorov

Hi,

Can someone briefly explain how exactly they defer the computation of the parameters ?
My humble knowledge in Java says just the opposite - first evaluate the params and then call the method itself passing the values (either primitives or reference addresses).
Probably I will read logback's docs/sources to find this out, but I'll be glad if someone share this technic with me.

Re: Closures and Logging by Rob Di Marco

Martin,

The deferring of computation is a performance issue. Consider the following function:


public void workOnDomObject(org.w3c.dom.Document doc) {
getLog().debug("Dump XML for debugging purposes: " + convertDOMDocumentToTxt(doc));
// do processing here
}


In the debug message, we are constructing the debug string which involves converting the DOM document to text. This is probably not a cheap operation, and it the expensive part is executed whether the debug mode is enabled or not because it is an argument to the function. Hence, you see a lot of code like:

if (getLog().isDebugEnabled() {
getLog().debug("");
}

This way there is no penalty for the creation of the log message unless it is used.

Re: Closures and Logging by David Skelly

Hi,

Can someone briefly explain how exactly they defer the computation of the parameters ?
My humble knowledge in Java says just the opposite - first evaluate the params and then call the method itself passing the values (either primitives or reference addresses).
Probably I will read logback's docs/sources to find this out, but I'll be glad if someone share this technic with me.


It doesn't defer computation of the parameters. That's what the article above means when it says:

It doesn't defer the cost of retrieving expensive parameters, such as the password crypting in the above example


Using a closure would be different, because in that case you do defer computation of the parameters. In other words, in the example given above everything between do and end is only executed if we are in debug.

Re: Closures and Logging by Geoffrey Wiseman

What David said. 'Computation of the parameters' is a better turn of phrase, really.

But, yes, LogBack can save the cost of message assembly, but not parameter computation. The above closure example saves computation of parameters as well, which is better still, but difficult to do in current Java syntax. It's not hard to imagine using something like the Callable interface and anonymous classes, but it would be comparatively ugly, and therefore only used when necessary:


logger.debug(
"User with account {} failed authentication; " +
"supplied crypted password {} " +
" does not match.", user.getAccount(),
new Callable<String>() {
public String call() {
return user.crypt(password);
} } ) );

Re: Closures and Logging by anjan bacchu

What David said. 'Computation of the parameters' is a better turn of phrase, really.

But, yes, LogBack can save the cost of message assembly, but not parameter computation. The above closure example saves computation of parameters as well, which is better still, but difficult to do in current Java syntax. It's not hard to imagine using something like the Callable interface and anonymous classes, but it would be comparatively ugly, and therefore only used when necessary:


logger.debug(
"User with account {} failed authentication; " +
"supplied crypted password {} " +
" does not match.", user.getAccount(),
new Callable<String>() {
public String call() {
return user.crypt(password);
} } ) );


Hi There,

Now that we have byte-code instrumentation(used by hibernate, spring and other tools including clover, emma, etc), can't we change the original

logger.debug( "User with account {} failed authentication; " +
"supplied crypted password {} does not match.",
user.getAccount(), user.crypt(password) );

to the Closure like syntax on the fly ?

Thank you,

BR,
~A

Re: Closures and Logging by anjan bacchu

What David said. 'Computation of the parameters' is a better turn of phrase, really.

But, yes, LogBack can save the cost of message assembly, but not parameter computation. The above closure example saves computation of parameters as well, which is better still, but difficult to do in current Java syntax. It's not hard to imagine using something like the Callable interface and anonymous classes, but it would be comparatively ugly, and therefore only used when necessary:


logger.debug(
"User with account {} failed authentication; " +
"supplied crypted password {} " +
" does not match.", user.getAccount(),
new Callable<String>() {
public String call() {
return user.crypt(password);
} } ) );


Hi There,

Now that we have byte-code instrumentation(used by hibernate, spring and other tools including clover, emma, etc), can't we change the original

logger.debug( "User with account {} failed authentication; " +
"supplied crypted password {} does not match.",
user.getAccount(), user.crypt(password) );

to the Closure like syntax on the fly ?

Thank you,

BR,
~A


"to the Closure like syntax on the fly ?"
Even if we can't do it on the fly, we could do it as part of a post-compilation step when we're ready to deploy for production/staging.

BR,
~A

Re: Closures and Logging by Martin Grigorov

Hi,
It doesn't defer computation of the parameters. That's what the article above means when it says:


It doesn't defer the cost of retrieving expensive parameters, such as the password crypting in the above example



Thanks David!

I didn't read carefully.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

9 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT