即使将level设置为info并且它是否有任何重大影响,记录器是否始终读取调试?

时间:2018-02-16 14:04:14

标签: java logging

正如标题所说。 如果我有

LOGGER.debug(model.toString())

我将日志记录级别设置为INFO,此行总是会被执行,如果是这样,如果你有很多调试日志记录,它会产生很大的影响吗? 我看过一些应用程序有一个名为debug = true的属性,而在代码中有类型

if(debug) {
    LOGGER.debug("log message");
}

这是一种更好的方法还是我应该继续使用LOGGER.debug()而不进行专业检查?

3 个答案:

答案 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进行惰性评估的信息很多,因此在此我不再赘述。