Log4j 2 lambda“惰性日志记录”

问题描述 投票:0回答:2

Log4j 2 手册给出了如何使用 lambda 进行“惰性日志记录”的示例:

logger.trace("Some long-running operation returned {}", () -> expensiveOperation());

还给出了如何使用格式参数来避免不必要的字符串连接的示例:

logger.debug("Logging in user {} with birthday {}", user.getName(), user.getBirthdayCalendar());

我的问题:通过简单地为一个 lambda 提供正常的字符串连接方法,我是否可以获得相同的性能优势?

logger.trace(() -> "Concatting " + user.getName() + " with " + expensiveOperation());
    
java logging lambda log4j log4j2
2个回答
8
投票
您的示例中表现最好的是

logger.trace("Concatting {} with {}", () -> user.getName(), () -> expensiveOperation());

这边

    除非调试级别为 TRACE,否则这两个方法都不会被调用
  1. 不会创建 String 对象:Log4j2 在幕后使用线程本地 StringBuilder 来实现无垃圾
  2. 您可以避免为字符串连接分配临时 StringBuilder(当您“+”两个字符串时 Java 在幕后所做的事情)

0
投票
如果您在无垃圾模式下使用 Log4J2,则可以使用最后一个代码示例。

logger.trace(() -> "Concatting " + user.getName() + " with " + expensiveOperation());

引自 Log4J2

Garbage-free Steady State Logging 页,截至 2023 年 11 月 1 日:

注意:并非所有日志记录都是无垃圾的。具体来说:

    记录 lambda
  • 作为参数 (logger.info("lambda value is {}", () -> callExpensiveMethod())
    ) 创建一个 vararg 数组。单独记录 lambda 表达式是无垃圾的:
    logger.debug(() -> callExpensiveMethod())
© www.soinside.com 2019 - 2024. All rights reserved.