Avoid Log4j/Slf4j debug enabled checks

2019-08-11 09:08发布

问题:

Almost in every project I use either Log4j or Slf4j with logback to log events and almost everywhere I have to write something like

if (log.isDebugEnabled()) {
    log.debug("I'm here doing this stuff");
}

Sometimes you don't see actual method logic with all these logging code. I cannot remove log.isDebugEnabled() checks because even if I use Slf4j with {} feature some log information might be calculated and dropped if debug (or whatever level) is not enabled.

log.debug("Here is the data: {}", calculateDataFromSeveralDataSourcesDuh());

Here is the question: Is there a way to postpone log info calculation, so it is calculated only when appropriate log level is enabled without checks in application code?

What are possible options if I cannot use Java 8 and I'm using Slf4j api, so Log4j2 is not available?

回答1:

By using Log4j2 and Java 8, you can easily make use of lambdas as described here, so in your case using debug(Message, Supplier) e.g.

    log.debug("Here is the data: {}", () -> calculateDataFromSeveralDataSourcesDuh());

In case you can't use log4j2 or java 8, have a look at the concept of object rendering in log4j. You can set up your own object renderer for specific classes, whose construction would be cheap in comparison to rendering it (involving your calculateDataFromSeveralDataSourcesDuh call). Assuming only parts of your debug information is costly to compute, it might be worthwhile to identify those situations and create custom classes (and corresponding object renderers) for them.