Wednesday, 6 June 2018

Lazy Logging with Log4j2 and Java 8+

Here's a good reason to switch to log4j2 and one I don't see enough people using yet.

At times we are reluctant to use log4j because of the overhead of evaluating the messages even where the log level does not apply to the current setting.  An alternative is to wrap our logging with a guard like so:

1
2
3
if (logger.isDebugEnabled()) {
    logger.debug("Debug something " + something.getInfo());
}

Littering our code with these guards makes our code look like it's more about logging than computing.

Log4j2 supports Java 8 and you can now lazily log in a couple of ways.

Lazily evaluating formatter arguments 

If you're using arguments in your messages you can replace the values with lambda expressions and their evaluation will be delayed 'till it's determined that the message needs to be written.

1
LOG.debug("a string with a parameter {}",  LazyLoggingClass::getString);

In this example getString won't be called unless we're at an appropriate log level to print debug messages.

Lazily evaluating the message argument

It's probably more common to use a string catenation expression in legacy logging.  It's also permitted to use a lambda expression for the message itself, so you can do this:


1
LOG.debug(() -> "Final result is " + getString() );

and getString() will only be called if we are going to log DEBUG messages.

No comments:

Post a Comment