有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Do logger始终读取调试,即使级别设置为info,它是否有任何重大影响?

正如标题所说。 如果我有

LOGGER.debug(model.toString())

我将日志记录级别设置为INFO,这一行会一直执行吗?如果是,如果有大量调试日志记录,会不会产生很大影响? 我见过一些应用程序具有名为debug=true的属性,并且在代码中

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

这是一个更好的方法还是我应该继续使用LOGGER。调试()而不进行proeprity检查


共 (3) 个答案

  1. # 1 楼答案

    日志类只是普通的Java类

    如果您的代码中有一个方法调用,它将被调用

    然而,所有日志框架的日志方法都被设计为在相关级别未启用时立即返回,这使得整个方法调用的成本很低,实际上什么都没有。因此,您几乎不应该使用if (debug)if (logger.isDebugEnabled())。他们根本没有节省时间

    然而,普通的Java方法仍然是普通的Java方法。执行此操作时:

    LOGGER.debug(model.toString());
    

    Java将首先调用model.toString(),然后将结果传递给记录器。与logger调用不同,如果toString方法做了大量工作和/或调用非常频繁,那么toString可能会非常昂贵。为了解决这个问题,日志框架有参数化的日志方法,只有在启用相关级别时,这些方法才会将参数转换为字符串

    使用java。util。登录中。记录器,它看起来像这样:

    logger.log(Level.FINE, "Model={0}", model);     // no toString() call
    

    使用SLF4J或Log4j:

    logger.debug("Model={}", model);                 // no toString() call
    
  2. # 2 楼答案

    这与记录器没有太大关系,而是与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!");
    }
    
  3. # 3 楼答案

    使用lambdas有一种更好的方法

    LOGGER.debug(() -> model.toString())
    

    这将确保仅当级别设置为调试时

    model.toString()

    将进行评估

    从本质上讲,这变成了对

    model.toString()

    要延迟评估

    关于在web上使用lambdas进行惰性评估,有相当多的信息,所以我不在这里重复