【发布时间】:2015-08-24 13:47:45
【问题描述】:
鉴于Java argument evaluation mechanism,Log4j 2.x在使用大括号格式化消息时如何实现lazy evaluation,以“避免参数构造成本”禁用日志?
例如
logger.debug("Entry number: {} is {}", i, entry[i]);
【问题讨论】:
标签: java log4j2 lazy-evaluation
鉴于Java argument evaluation mechanism,Log4j 2.x在使用大括号格式化消息时如何实现lazy evaluation,以“避免参数构造成本”禁用日志?
例如
logger.debug("Entry number: {} is {}", i, entry[i]);
【问题讨论】:
标签: java log4j2 lazy-evaluation
我猜 Log4j 的意思是,用大括号,它们避免在不需要时构造字符串(例如,Level 不是 Debug):
有
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
即使没有记录,也始终会计算完整的消息。
有
logger.debug("Entry number: {} is {}", i, entry[i]);
Log4j 可以先检查 Log-Level,然后决定是否值得构造消息字符串。这节省了字符串连接所需的资源。如果消息实际正在创建,它只会在提供的对象上调用toString(),从而节省更多的计算成本。
Log4j 使用一个内部类 (org.apache.logging.log4j.message.ParameterFormatter) 将每个 {} 替换为提供的参数。它还会捕获toString() 抛出的异常并报告这些故障。
【讨论】:
为避免参数评估,只需将其包装在 lambda 中:
logger.debug(() -> {
"Entry number: " + i + " is " + String.valueOf(entry[i])
});
在这种形式中,只有在实际伐木之前,才会要求供应商进行施工。把它想象成一个函数声明。
【讨论】: