【问题标题】:Unable to understand why to use parameterized logging无法理解为什么要使用参数化日志记录
【发布时间】:2017-09-14 15:04:09
【问题描述】:

我正在阅读 Java 中的参数化日志记录,据说使用参数化日志记录而不是串联,因为它执行惰性求值。

所以不是

logger.debug("My text is" + x);

使用:

logger.debug("My text is {}", x);

如果跟踪级别设置为仅信息日志,为什么在第一种情况下会发生串联?

另外,如果我在日志中有一个耗时的功能,据说使用:

logger.debug("My text is {}", () -> compute());

而不是

logger.debug("My text is {}", compute());

在这种情况下,为什么 lambda 方法被认为是更好的方法。不会像在字符串连接情况下一样懒惰地调用计算吗?

【问题讨论】:

    标签: java logging java-8


    【解决方案1】:

    在输入logger.debug()之前,必须计算参数。

    在第一种情况下,您总是在将结果字符串传递给方法(可能不会使用它)之前获得字符串连接。使用参数化版本没有进行连接,x 被传入并且可以使用也可以不使用。

    compute() 相同。非 lambda 版本总是会在进入方法之前执行compute(),因为它需要compute() 的结果才能调用方法。

    lambda版本会将方法(实际上是一个Supplier,它在请求结果时运行该方法)作为参数而不是方法结果,只有在需要时才会执行.

    【讨论】:

    • 感谢您的详细解释。这是否意味着在调用任何函数之前,首先评估所有参数,然后调用函数
    • @user1692342,是的,如果它需要一些参数
    • @user1692342 没错。 lambda 方法只允许将参数评估为运行compute()Supplier。所以它已经被完全评估过了,但是实际的compute() 方法还没有运行。
    【解决方案2】:

    这个想法很简单。通常,应用程序使用记录器的频率很高,但记录日志本身是一种消耗资源的操作,至少因为您需要向硬盘驱动器写入一些东西。看看你的例子:

    logger.debug("My text is " + x);
    

    让我们假设在记录器配置中打开了 INFO 级别。然后代码执行这一行,它需要评估参数以传入debug函数,所以它确实如此。但是在debug logger 内部会检查打开了哪个日志级别,它将是INFO。在这种情况下不应记录您想要的消息,因此组装参数字符串所需的计算将被视为浪费时间。 为了克服此类问题,您可以在调用方法之前检查日志级别是否已转,如下所示

    if (logger.isDebugEnabled()) {
        logger.debug("My text is " + x)
    }
    

    这会更好,因为您只会组装需要的消息,但这里的问题是logger.isDebugEnabled() 评估了两次。首先在您的代码中,然后在 logger.debug() 中。 这就是建议参数化日志记录的原因,因为它把这两个问题都抛在了脑后。 这同样适用于 lambdas 建议的耗时操作。希望它现在对您有所帮助并且有点清楚!

    【讨论】:

      【解决方案3】:

      这与Optional.orElse()Optional.orElseGet() 几乎相同,第二个仅在需要时调用。

      我假设记录器内部检查如下:

      if(logLevel.isDebug()){
      
             Value v = supplier.get(); 
             // log v
      }
      

      假设您的 lambda 使用一些繁重的调用来计算该值(例如 DB call),您当然不希望一直计算,只有在需要时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-20
        • 2021-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-21
        相关资源
        最近更新 更多