正如标题所说。 如果我有
LOGGER.debug(model.toString())
我将日志记录级别设置为INFO,此行总是会被执行,如果是这样,如果你有很多调试日志记录,它会产生很大的影响吗? 我看过一些应用程序有一个名为debug = true的属性,而在代码中有类型
if(debug) {
LOGGER.debug("log message");
}
这是一种更好的方法还是我应该继续使用LOGGER.debug()而不进行专业检查?
答案 0 :(得分:6)
记录类只是普通的Java类。
如果您的代码中有方法调用,则会调用它。
然而......如果没有启用相关级别,所有日志记录框架的日志方法都会立即返回,这使得整个方法调用的成本非常低,基本上没什么。因此,您几乎不应该使用if (debug)
或if (logger.isDebugEnabled())
。他们根本没有节省任何时间。
但是,普通的Java方法仍然是普通的Java方法。执行此操作时:
LOGGER.debug(model.toString());
Java将首先调用model.toString()
,然后将结果传递给记录器。与记录器调用不同,如果toString方法执行大量工作和/或非常频繁地调用,则toString 可能很昂贵。为了解决这个问题,日志记录框架具有参数化日志方法,只有在启用相关级别时才会将参数转换为字符串。
使用java.util.logging.Logger,它看起来像这样:
logger.log(Level.FINE, "Model={0}", model); // no toString() call
使用SLF4J或Log4j:
logger.debug("Model={}", model); // no toString() call
答案 1 :(得分:1)
这与记录器没什么关系,但是评估了Java中表达式的所有内容。与例如进行延迟评估的Haskell相反,Java中参数列表中的所有表达式总是被评估,但布尔快捷方式除外。
所以,如果你这样做:
LOGGER.debug(model.toString());
无论您的日志记录级别如何,始终会对此进行评估。这就是您应该始终使用此表单的原因:
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(model.toString());
}
拨打isDebugEnabled()
的影响可以忽略不计。
Java停止评估的一次是,布尔表达式是否已确定为false
,因此不会抛出异常:
if (1 == 0 && 0 / 0 > 0) {
System.out.println("Hello, world!");
}
答案 2 :(得分:1)
对于lambda,有一种更好的方法。
LOGGER.debug(() -> model.toString())
这将确保仅当级别设置为调试时,
model.toString()
将被评估。
本质上,这将成为对
的热切评价model.toString()
懒惰评估。
关于在网络上使用lambda进行惰性评估的信息很多,因此在此我不再赘述。