在使用logger.debug()之前是否需要Log4j isDebugEnabled()?[重复]

bmp9r5qi  于 2023-04-20  发布在  其他
关注(0)|答案(5)|浏览(223)

此问题已在此处有答案

Is there a need to do a if(log.isDebugEnabled()) { ... } check? [duplicate](5个答案)
7年前关闭。
当我在浏览一些代码时,我注意到logger的使用如下所示,

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

但在一些代码中,我是这样观察的。

logger.debug("Something..");

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

nhjlsmyf

nhjlsmyf1#

当传递给logger.debug(...)的String需要时间进行求值时,它很有用,在这种情况下,如果没有启用debug,您可以跳过此求值。

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

在我看来,这使得代码的可读性大大降低,所以只有在性能有显著提高的时候才应该使用它。

原答案10年后编辑:

现在我们有了lambdas,日志记录器增加了对只在必要时调用的供应者的支持。因此上面的代码可以简化为:

logger.debug("The meaning of life is {}", () -> calculateMeaningOfLife());

如果消息应该被记录,记录器将只调用calculateMeaningOfLife()

o2g1uqev

o2g1uqev2#

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

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

首先调用Strings concatination,然后调用debug(),然后Logger检测到debug未启用并简单返回。这可能会显著影响应用程序的性能。
这个问题在SLF4J中得到了解决,它具有如下格式的日志记录方法

public void debug(String format, Object arg);
xwmevbvl

xwmevbvl3#

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

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

上面的代码将导致创建多个String对象,因为each +创建另一个String,所以在调用该方法之前,您将创建大约5个或更多对象。
大多数情况下不会启用调试,因此检查是否启用了调试比始终解析参数更有效。

ycl3bljg

ycl3bljg4#

声明:

if(log.isDebugEnabled()){

仅出于性能原因使用。它的使用是可选的,因为它是由log方法内部调用的。
但现在你问这个检查是不是内部做的,那我为什么要用呢?很简单:如果您记录如下简单内容:

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

然后你不需要做任何检查。如果你使用append操作符(+)编写一个要记录的字符串,如下所示:

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

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

oknwwptz

oknwwptz5#

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());
    }
}

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

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

另一件事是,Logger的实现是可以改变的,所以如果你想确保你的logger总是根据它的日志记录级别被调用,那么你可能想考虑使用isDebugEnabled()方法。

相关问题