是否需要执行if(log.isDebugEnabled()){...}检查?

时间:2011-06-28 09:32:37

标签: java if-statement log4j logging

是否需要进行显式if(log.isDebugEnabled()){...}检查?

我的意思是我看到一些帖子提到log.debug(“something”)在进行日志记录之前进行隐式调用以查看是否已启用调试模式日志记录。我错过了什么,或者在使用它之前是否有中间步骤?

谢谢!

log.debug("ResultSet rs is retrieved from OracleTypes");

vs

if(log.isDebugEnabled()){
     log.debug("ResultSet rs is retrieved from OracleTypes");
}

编辑: 写了这个: http://java.sg/whether-to-do-a-isdebugenabled-checking-before-printing-out-your-log-statement/

5 个答案:

答案 0 :(得分:65)

声明:

if(log.isDebugEnabled()){

仅用于性能原因。它的使用是可选的,因为它在内部由log方法调用。

但是现在你问这个检查是否在内部进行,那我为什么要使用呢? 这很简单:如果你记录的内容很简单:

log.debug("ResultSet rs is retrieved from OracleTypes");

然后你不需要做任何检查。如果使用追加运算符(+)组成一个字符串来记录,如下所示:

log.debug("[" + System.getTimeInMillis() + "] ResultSet rs is retrieved from OracleTypes");

在这种情况下,您应该检查日志是否已启用,因为如果不是,即使没有创建日志,字符串组成也是如此。我必须提醒你,使用运算符“+”来连接字符串是非常低效的。

答案 1 :(得分:33)

我知道这是旧的,但对于任何只是发现这个的人来说......

如果使用SLF4J,则可以使用消息格式避免isDebugEnabled()调用。

例如,而不是:

Object entry = new SomeObject();
logger.debug("The entry is " + entry + ".");

使用:

Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);

除非启用调试,否则不会评估消息格式。

因此,对于简单的情况,您可以避免使用isDebugEnabled()。

但是在构建其中一个参数可能很昂贵的情况下,您仍然希望使用isDebugEnabled()(即使使用SLF4J)。

例如:

if (logger.isDebugEnabled()) {
    logger.debug("Here is the SQL: {}", sqlWrapper.buildSQL());  // assume buildSQL() is an expensive operation
}

在这种情况下,除非实际启用了调试,否则您不想评估buildSQL()。

对于SLF4J,有一些关于使用它总是与选择性地使用它的争论。这真的归结为个人偏好。您可能希望在任何地方使用,以防止其他开发人员(在不知不觉中)将您的日志消息更改为更复杂/更昂贵的东西。

答案 2 :(得分:8)

Logger的最新版本简化了这一点,所以差别不大。

最大的区别是你不必创建要记录的东西 - 有时会有很多字符串添加。

答案 3 :(得分:7)

我通过执行代码中的检查与未执行检查来检查以下代码。有趣的是,如果在我们的代码中执行检查,执行了一百万次执行的4个日志语句,则额外需要400毫秒。我正在使用SLF4J 1.6.6。如果你能负担得起每百万请求400毫秒,你就不需要支票了。

    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
        if (logger.isTraceEnabled()) {
            logger.trace(request.getUserID());
            logger.trace(request.getEntitlementResource().getResourceString());
            logger.trace(request.getEntitlementResource().getActionString());
            logger.trace(request.getContextMap());
        }
    }
    long endTime = System.currentTimeMillis();
    logger.fatal("With Check Enabled : " + (endTime - startTime) + " ms");

    startTime = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {

        logger.trace(request.getUserID());
        logger.trace(request.getEntitlementResource().getResourceString());
        logger.trace(request.getEntitlementResource().getActionString());
        logger.trace(request.getContextMap());

    }
    endTime = System.currentTimeMillis();
    logger.fatal("With Check Disabled : " + (endTime - startTime)  + " ms");

--- --- OUTPUT

* 2016-01-07 10:49:11,501 ERROR [:http-bio-8080-exec-3] [com.citi.cmb.entitlement.service.EntitlementServiceImpl] [] - 启用检查: 661毫秒

2016-01-07 10:49:57,141 ERROR [:http-bio-8080-exec-3] [com.citi.cmb.entitlement.service.EntitlementServiceImpl] [] - 禁用检查: 1043毫秒

答案 4 :(得分:1)

这样做的原因是出于性能原因。如果首先检查,则不应评估log.debug(...语句。

确实在功能上是相同的。