Even with slf4j, should you guard your logging?

Writing and reading all those if(logger.isDebugEnabled()) {} will probably cost as much time as they save you.

Of course, calling the log method isn't free but the same is true for calling isDebugEnabled(). So you're paying more for each log statement that is active if you use this pattern (because the logging framework will check the level twice).

It also clutters the code.

In practice, I haven't found the performance penalty to be big enough to bother.

If logging is too slow for you, write an non-blocking appender that pushes the log events into a queue without only a few checks and use a background thread to process them.

Background: The standard appenders are all synchronized so logging in a multi-threaded application can cause lots of small pauses where all threads wait for a log message to be written to a file.


I'll try to put my two cents from another perspective

What is exactly the benefit of parametrized logging?

You just defer toString() invocation and string concatenation until really needed, which is when you really have to log the message. This optimizes performance when that particular logging operation is disabled. Check source code for SLF4J if not sure.

Does parametrized logging makes guards useless in all cases?

No.

In which cases would logging guards be of use?

When there are other potential expensive operations.

For example (in the case this particular logging operation is disabled), if we have no logging guard

logger.debug("User name: {}", getUserService().getCurrentUser());
  1. We would pay the cost from obj = getUserService().getCurrentUser()
  2. We would save the cost from "User name: " + obj.toString()

If we use logging guard:

if (logger.isDebugEnabled()) {
    logger.debug("User: {}", getUserService().getCurrentUser());
}
  1. We would pay the cost of logger.isDebugEnabled()
  2. We would save the cost from obj = getUserService().getCurrentUser()
  3. We would save the cost from "User name: " + obj.toString()

In the later case, we would save both costs at the price of checking isDebugEnabled() twice when this particular logging operation is enabled.

NOTE: This is just an example, not trying to debate good/bad practices here.