当我浏览一些代码时,我注意到使用logger如下,
if(logger.isDebugEnabled())
logger.debug("Something..");
但在某些代码中,我发现了这样的情况。
logger.debug("Something..");
当我查看log4j的来源时,在Logger自身的debug()
方法if(logger.isDebugEnabled())
中进行了检查。那么为什么我们需要这种不必要的开销if(logger.isDebugEnabled())
??
答案 0 :(得分:40)
当传递给logger.debug(...)
的字符串需要时间来评估时很有用,在这种情况下,如果未启用调试,则可以跳过此评估。
if(logger.isDebugEnabled()) {
logger.debug("The meaning of life is " + calculateMeaningOfLife());
}
IMO会使代码的可读性降低,因此只有在性能显着提高时才能使用。
答案 1 :(得分:12)
isDebugEnabled通常用于避免不必要的字符串连接,例如此调用
logger.debug("Line number = " + n);
首先调用Strings concatination然后调试debug()然后只有Logger检测到调试没有启用并且只是返回。这可能会严重影响应用性能。
SLF4J解决了这个问题,SLF4J格式化了这样的日志记录方法
public void debug(String format, Object arg);
答案 2 :(得分:4)
Java必须首先解析传递给调试方法的字符串参数才能调用它。
logger.debug("Something.. var1=" + variable1 + " var2=" + variable2);
上面的代码将导致创建多个String对象,因为每个+创建另一个String,因此在调用方法之前,您将创建大约5个或更多对象。
调试通常不会启用,因此检查启用调试是否比一直解析参数更有效。
答案 3 :(得分:3)
声明:
if(log.isDebugEnabled()){
仅用于性能原因。它的使用是可选的,因为它在内部由log方法调用。
但是现在你问这个检查是否在内部进行,那我为什么要使用呢?这很简单:如果你记录的内容很简单:
log.debug("ResultSet rs is retrieved from OracleTypes");
然后你不需要做任何检查。如果使用追加运算符(+)组成一个字符串来记录,如下所示:
log.debug("[" + System.getTimeInMillis() + "] ResultSet rs is retrieved from OracleTypes");
在这种情况下,您应该检查日志是否已启用,因为如果不是,即使没有创建日志,字符串组成也是如此。我必须提醒你,使用运算符“+”来连接字符串是非常低效的。
答案 4 :(得分:1)
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()
方法。