I was reading upon parameterized logging in Java, it is said to use parameterized logging instead of concatenation as it performs lazy evaluation.
So instead of
logger.debug("My text is" + x);
use:
logger.debug("My text is {}", x);
If the trace level is set to only info logs, why does the concatenation happen in the first scenario?
Also if I have a time consuming function in log, it is said to use:
logger.debug("My text is {}", () -> compute());
instead of
logger.debug("My text is {}", compute());
In this case, why is the lambda method considered a better approach. Won't compute also be called lazily like in the string concatenation case?
Before you enter logger.debug()
the parameters must be calculated.
In the first case, you always get String concatenation before passing the resulting String to the method (which may not use it). With the parameterized version no concatenation is done, the x
is passed in and may be used or not.
Same deal with compute()
. The non-lambda version will always execute compute()
before entering the method, because it will need the result of compute()
in order to invoke the method.
The lambda version will pass the method (actually a Supplier
which runs the method when the result is requested) as a parameter instead of the method result, and it will only be executed if needed.
The idea is the simple. Usually, applications use logger very frequently, but logging itself is resource-consuming operation, at least because you need to write something to hard drive. Looking at your example:
logger.debug("My text is " + x);
Let's imagine that INFO level turned on in the logger configuration. Then the code executes this line, it needs to evaluate parameter to pass in debug
function, so it does. But inside debug
logger will check which log level turned on and it will be INFO. The message you want should not be logged in this case, so the calculations required to assembly the parameter string will be considered as waste of time.
To overcome such problems you can check if the log level turned before calling method, like this
if (logger.isDebugEnabled()) {
logger.debug("My text is " + x)
}
It will be better, because you will assemble message only it's required, but the problem here is that logger.isDebugEnabled()
evaluated twice. First inside your code and then inside logger.debug()
.
That's why parametrized logging suggested, because it left both these problems behind.
The same applicable for time-consuming operations where lambdas suggested. Hope it helps and a bit clear for you now!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With