Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Log4j 2.x implement lazy argument evaluation?

Given the Java argument evaluation mechanism, how does Log4j 2.x implement lazy evaluation when formatting the message with curly brackets "to avoid the cost of parameter construction" when log is disabled?

e.g.

logger.debug("Entry number: {} is {}", i, entry[i]);
like image 202
Linuslabo Avatar asked Aug 24 '15 13:08

Linuslabo


2 Answers

I guess what Log4j means, is that with the curly brackets, they avoid constructing a string when its not necessary (e.g. the Level is not Debug):

With

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));

the complete message is always computed even when it will not be logged.

With

logger.debug("Entry number: {} is {}", i, entry[i]);

Log4j can check the Log-Level first and then decide if its worth to construct the message string. This saves resources needed for string concatenation. It will only call toString() on the objects supplied if the message is actually being created, saving further computation costs.

Log4j uses an internal class (org.apache.logging.log4j.message.ParameterFormatter) that replaces every {} with the arguments provided. It will also catch exceptions thrown by toString() and report these failures.

like image 163
hinneLinks Avatar answered Sep 20 '22 15:09

hinneLinks


To avoid argument evaluation, just wrap it in lambda:

logger.debug(() -> { 
   "Entry number: " + i + " is " + String.valueOf(entry[i])
});

In this form, the supplier will be called for construction only before actual logging. Think of it like a function declaration.

like image 35
Yuriy Mankovskiy Avatar answered Sep 23 '22 15:09

Yuriy Mankovskiy