Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In log4j, does checking isDebugEnabled before logging improve performance?

People also ask

Do we need to check isDebugEnabled?

If you can afford to loose 400 ms per million request ,you don't need the check.

What is isDebugEnabled?

The guard statement (checking isDebugEnabled() ) is there to prevent potentially expensive computation of the log message when it involves invocation of the toString() methods of various objects and concatenating the results.

Does logging affect performance?

Logs Can Have a Strong Impact on Stability, Performance, and Garbage Collection.

How do I enable debug mode in Log4j properties?

You need to set the logger level to the lowest you want to display. For example, if you want to display DEBUG messages, you need to set the logger level to DEBUG. The Apache log4j manual has a section on Configuration. Show activity on this post.


In this particular case, Option 1 is better.

The guard statement (checking isDebugEnabled()) is there to prevent potentially expensive computation of the log message when it involves invocation of the toString() methods of various objects and concatenating the results.

In the given example, the log message is a constant string, so letting the logger discard it is just as efficient as checking whether the logger is enabled, and it lowers the complexity of the code because there are fewer branches.

Better yet is to use a more up-to-date logging framework where the log statements take a format specification and a list of arguments to be substituted by the logger—but "lazily," only if the logger is enabled. This is the approach taken by slf4j.

See my answer to a related question for more information, and an example of doing something like this with log4j.


Since in option 1 the message string is a constant, there is absolutely no gain in wrapping the logging statement with a condition, on the contrary, if the log statement is debug enabled, you will be evaluating twice, once in the isDebugEnabled() method and once in debug() method. The cost of invoking isDebugEnabled() is in the order of 5 to 30 nanoseconds which should be negligible for most practical purposes. Thus, option 2 is not desirable because it pollutes your code and provides no other gain.


Using the isDebugEnabled() is reserved for when you're building up log messages by concatenating Strings:

Var myVar = new MyVar();
log.debug("My var is " + myVar + ", value:" + myVar.someCall());

However, in your example there is no speed gain as you're just logging a String and not performing operations such as concatenation. Therefore you're just adding bloat to your code and making it harder to read.

I personally use the Java 1.5 format calls in the String class like this:

Var myVar = new MyVar();
log.debug(String.format("My var is '%s', value: '%s'", myVar, myVar.someCall()));

I doubt there's much optimisation but it's easier to read.

Do note though that most logging APIs offer formatting like this out of the box: slf4j for example provides the following:

logger.debug("My var is {}", myVar);

which is even easier to read.


In Java 8, you don't have to use isDebugEnabled() to improve the performance.

https://logging.apache.org/log4j/2.0/manual/api.html#Java_8_lambda_support_for_lazy_logging

import java.util.logging.Logger;
...
Logger.getLogger("hello").info(() -> "Hello " + name);