Log4j 2 lambda“lazy logging”

t3irkdon  于 6个月前  发布在  其他
关注(0)|答案(2)|浏览(96)

Log4j 2 manual给出了一个关于如何使用logdas进行“延迟日志记录”的示例:

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());

a7qyws3x

a7qyws3x1#

在您的示例中,最具性能的是

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

字符串
这种方式
1.除非调试级别为TRACE,否则不会调用这两个方法
1.没有创建String对象:Log4j2在后台使用了一个线程本地StringBuilder来避免垃圾
1.避免为String连接分配临时StringBuilder(Java在“+”两个String时所做的)

yzuktlbb

yzuktlbb2#

如果您在无垃圾模式下使用Log4J 2,那么最后一个代码示例就是最好的方法。

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

字符串
引用自Log4J 2 Garbage-free Steady State Logging页面,截至2023-11-01:

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

  • 记录lambda * 作为参数 *(logger.info("lambda value is {}", () -> callExpensiveMethod()))创建一个vararg数组。记录lambda表达式本身是无垃圾的:logger.debug(() -> callExpensiveMethod())

相关问题