为什么要为logger.debug()使用额外的if条件?

时间:2012-11-07 10:45:24

标签: java log4j

  

可能重复:
  In log4j, does checking isDebugEnabled before logging improve performance?

我见过以下方式使用log4j的人:

if(logger.isDebugEnabled())
{
    logger.debug(" message ");
}

但是,我检查了logger.debug API的文档,发现它在检查邮件之前检查是否启用了debug。在那种情况下,写出额外的if是什么意思?

只是写

并不完全一样
logger.debug(" message ");

6 个答案:

答案 0 :(得分:21)

如果你真的只是写

logger.debug(" message ");
然后没有任何好处。但请考虑:

logger.debug("This: " + message + " happened on thread " + thread +
            "because " + cause);

您不希望字符串连接(以及更昂贵的转换,可能 - 考虑您可能想要记录的内容,但转换为字符串的成本很高),如果结果就会被扔掉。

如果日志记录在正常情况下会对性能产生重大影响,那么添加日志记录代码就会受到阻碍,这些代码可能真正在突然想要启用诊断的情况下帮助您。

答案 1 :(得分:7)

我认为这里的想法是防止任何参数评估 - 在你的情况下它很简单,但是例如让我们说它更像是:

logger.debug("Foo" + bar() + " bar: " + foo());

好的,这是设计的,但如果未启用调试,您可能不想执行bar()foo()以及字符串连接...

答案 2 :(得分:2)

一个原因可能是因为构建消息会产生一些开销。例如:

if(debug.isDebugEnabled()) {
    String message = buildLogMessage()
    logger.debug(message);
}

如果buildLogMessage()需要一段时间才能运行,当您知道输出永远不会被记录时,您可能不想运行它。

但是,更好的解决方法是使用ObjectRender,这样只有在记录值时才能转换为String。

答案 3 :(得分:1)

如果你花一点时间看看log4j的实现,你可以知道是什么原因。当你写:logger.debug(" message "); log4j appender总是附加loggingEvent。这是昂贵的转换。 if条件最好,但在某些情况下很有用。

// AppenderAttachableImpl.class
public int appendLoopOnAppenders(LoggingEvent event) {
        int size = 0;
        if (appenderList != null) {
            size = appenderList.size();
            for (int i = 0; i < size; i++) {
                Appender appender = (Appender) appenderList.elementAt(i);
                appender.doAppend(event);
            }

        }
        return size;
    }

答案 4 :(得分:1)

另一个原因是修改HotSpot VM的行为。不太确定它是如何工作的,但是如果你在生产模式下运行(调试注销) - HotSpot VM应该优化代码,好像if语句和里面的所有东西都没有。

答案 5 :(得分:0)

在调用调试方法之前,可以执行可以通过条件语句避免的代码,例如字符串连接。例如:

log.debug("Value of variable1:"+variable+" Value of variable2:"+variable2);

如果在log.isDebugEnabled()中添加条件,则不执行字符串连接。

这是唯一的好处。