【问题标题】:Is Log4j isDebugEnabled() necessary before using logger.debug()? [duplicate]在使用 logger.debug() 之前是否需要 Log4j isDebugEnabled()? [复制]
【发布时间】:2013-07-25 06:29:44
【问题描述】:

在浏览一些代码时,我注意到logger的使用如下,

if(logger.isDebugEnabled())   
    logger.debug("Something..");

但在某些代码中,我观察到这样。

logger.debug("Something..");

查看log4j的源码时,在Logger本身的debug()方法中if(logger.isDebugEnabled())被勾选了。那为什么我们需要这种不必要的开销if(logger.isDebugEnabled())??

【问题讨论】:

    标签: java log4j


    【解决方案1】:

    当您传递给logger.debug(...) 的字符串需要时间来评估时很有用,在这种情况下,如果未启用调试,您可以跳过此评估。

    if(logger.isDebugEnabled()) {
        logger.debug("The meaning of life is " + calculateMeaningOfLife());
    }
    

    IMO 这使得代码的可读性大大降低,因此只有在性能显着提高时才应使用它。

    【讨论】:

      【解决方案2】:

      isDebugEnabled 通常用于避免不必要的字符串连接,例如这个调用

      logger.debug("Line number = " + n);
      

      首先调用字符串连接,然后调用 debug(),然后 Logger 才检测到调试未启用并简单地返回。这可能会显着影响应用性能。

      这个问题在 SLF4J 中解决了,它有像这样格式化的日志记录方法

      public void debug(String format, Object arg);
      

      【讨论】:

        【解决方案3】:

        Java 必须先解析传递给调试方法的字符串参数,然后才能调用它。

        logger.debug("Something.. var1=" + variable1 + "  var2=" + variable2);
        

        上述代码将导致创建多个 String 对象,因为每个 + 创建另一个 String ,因此在调用该方法之前您将创建大约 5 个或更多对象。

        调试大多不会启用,因此检查是否启用调试比一直解析参数更有效。

        【讨论】:

          【解决方案4】:

          声明:

          if(log.isDebugEnabled()){
          

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

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

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

          那么你不需要做任何检查。如果您像这样使用附加运算符 (+) 编写要记录的字符串:

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

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

          【讨论】:

            【解决方案5】:

            SLF4J 实现(检查版本 1.7.10)在某些方法中调用 isDebugEnabled(),例如:

            public void debug(String format, Object... arguments) {
                if(this.log.isDebugEnabled()) {
                    FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
                    this.log.debug(ft.getMessage(), ft.getThrowable());
                }
            }
            

            但也有一些方法重载不会在内部检查是否启用了给定的登录级别,例如:

            public void debug(String msg, Throwable t) {
                this.log.debug(msg, t);
            }
            

            另一件事是 Logger 实现可以更改,因此如果您想始终确保根据其日志记录级别调用您的记录器,那么您可能需要考虑使用 isDebugEnabled() 方法。

            【讨论】:

              猜你喜欢
              • 2010-11-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-09-12
              相关资源
              最近更新 更多