Log4j如何实现惰性参数评估?

Lin*_*abo 13 java log4j lazy-evaluation

鉴于Java参数评估机制,当禁用日志时,Log4j如何在使用大括号格式化消息"以避免参数构造的成本"时实现延迟评估

例如

logger.debug("Entry number: {} is {}", i, entry[i]);
Run Code Online (Sandbox Code Playgroud)

hin*_*nks 18

我想Log4j的意思是,使用大括号,它们避免在不需要时构造一个String(例如Level不是Debug):

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
Run Code Online (Sandbox Code Playgroud)

即使未记录字符串,也始终计算字符串.

logger.debug("Entry number: {} is {}", i, entry[i]);
Run Code Online (Sandbox Code Playgroud)

Log4j可以先检查Log-Level,然后决定构造Message-String是否值得.

Log4j使用一个内部的Class(org.slf4j.helpers.MessageFormatter)来替换每个{}提供的参数.您可以查看源代码org.slf4j.impl.Log4jLoggerAdapter.debug(String, Object[])

  • 明确.所以它只是推迟了String构造而不是参数评估. (3认同)
  • @Vadzim 感谢您的提示,当时我的类路径上必须有 SLF4j,然后就进入了错误的兔子洞。截至问题中的示例和 log4j2 的链接,问题是关于 log4j2,而不是 log4j 1.x。我更新了问题,以使其更清楚。 (2认同)

Yur*_*kiy 5

为避免参数评估,只需将其包装在 lambda 中:

logger.debug(() -> { 
   "Entry number: " + i + " is " + String.valueOf(entry[i])
});
Run Code Online (Sandbox Code Playgroud)

在这种形式中,供应商只会在实际伐木之前被要求进行施工。把它想象成一个函数声明。