我在我的应用程序中使用Log4J进行日志记录。之前我使用的调试调用如下:

选项1:

logger.debug("some debug text");

但是一些链接建议最好先检查isDebugEnabled(),比如:

选项2:

boolean debugEnabled = logger.isDebugEnabled();
if (debugEnabled) {
    logger.debug("some debug text");
}

所以我的问题是“选项2是否能提高性能?”

因为在任何情况下Log4J框架对debugEnabled都有相同的检查。对于选项2,如果我们在一个方法或类中使用多个调试语句可能是有益的,这样框架就不需要多次调用isDebugEnabled()方法(每次调用);在这种情况下,它只调用isDebugEnabled()方法一次,如果Log4J被配置为调试级别,那么实际上它会调用isDebugEnabled()方法两次:

如果将值分配给debugEnabled变量,和 实际上由logger.debug()方法调用。

我不认为如果我们在方法或类中编写多个logger.debug()语句并根据选项1调用debug()方法,那么与选项2相比,Log4J框架的开销是很大的。由于isDebugEnabled()是一个非常小的方法(就代码而言),因此它可能是内联的良好候选方法。


当前回答

它提高了速度,因为在调试文本中连接字符串是很常见的,这是昂贵的,例如:

boolean debugEnabled = logger.isDebugEnabled();
if (debugEnabled) {
    logger.debug("some debug text" + someState);
}

其他回答

它提高了速度,因为在调试文本中连接字符串是很常见的,这是昂贵的,例如:

boolean debugEnabled = logger.isDebugEnabled();
if (debugEnabled) {
    logger.debug("some debug text" + someState);
}

对于单行,我在日志消息中使用了三元,这样我就不做拼接:

ej:

logger.debug(str1 + str2 + str3 + str4);

我做的事:

logger.debug(logger.isDebugEnable()?str1 + str2 + str3 + str4:null);

但是对于多行代码

ej.

for(Message mess:list) {
    logger.debug("mess:" + mess.getText());
}

我做的事:

if(logger.isDebugEnable()) {
    for(Message mess:list) {
         logger.debug("mess:" + mess.getText());
    }
}

Log4j2允许您将参数格式化为消息模板,类似于String.format(),因此不需要执行isDebugEnabled()。

Logger log = LogManager.getFormatterLogger(getClass());
log.debug("Some message [myField=%s]", myField);

简单的log4j2.properties示例:

filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d %-5p: %c - %m%n
appender.console.filter.threshold.type = ThresholdFilter
appender.console.filter.threshold.level = debug
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = STDOUT

自从Log4j版本2.4 (orslf4j-api 2.0.0-alpha1)以来,使用流畅的API(或Java 8 lambda对惰性日志的支持)要好得多,支持Supplier<?>为日志消息参数,可以由lambda给出:

log.debug("Debug message with expensive data : {}", 
           () -> doExpensiveCalculation());

OR与slf4j API:

log.atDebug()
            .addArgument(() -> doExpensiveCalculation())
            .log("Debug message with expensive data : {}");

由于许多人在搜索log4j2时可能会看到这个答案,而且几乎所有当前的答案都不考虑log4j2或它最近的变化,因此这应该能够回答这个问题。

log4j2支持供应商(目前是它们自己的实现,但根据文档,计划在3.0版本中使用Java的供应商接口)。你可以在手册里读到更多。这允许你把昂贵的日志消息创建到一个供应商,它只创建消息,如果它将被记录:

LogManager.getLogger().debug(() -> createExpensiveLogMessage());