我在我们的项目中使用logback。我已经浏览了大括号的登录链接。
logger.debug(" My class output value - {}, object toString() {}", object.value(), object.toString());
我的项目中未启用调试。我们看到 toString(( 在我们的项目中被调用,这影响了我们的性能。在禁用调试的代码执行期间会调用 toString(( 吗?
我可以在这种方法中使用 toString(( 吗?因为根据大括号的定义字符串 concat 不会发生。它仅适用于字符串连接还是也适用于方法调用?
来自 LogBack 文档:
Better alternative
There exists a convenient alternative based on message formats. Assuming entry is an object, you can write:
Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);
Only after evaluating whether to log or not, and only if the decision is positive, will the logger implementation format the message and replace the '{}' pair with the string value of entry. In other words, this form does not incur the cost of parameter construction when the log statement is disabled.
因此,通过只传递对象而不调用 toString((,您将节省 toString(( 开销。
Logback 不会改变 Java 的规则:当你调用一个方法时,需要计算该方法的参数才能传递给该方法。未启用日志级别时,使用大括号表示法节省的只是字符串串联的成本,即构造要从各个组件记录的完整字符串的成本。
如果评估参数的成本显著降低性能,以至于无法满足客户的需求,则在未启用日志级别时,您可能希望避免运行它的成本。摘自 Logback 手册第 2 章:体系结构"参数化日志记录":
避免参数构造成本的一种可能方法是用测试包围日志语句。下面是一个示例。
if(logger.isDebugEnabled()) { logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); }
这样,如果对
logger
禁用调试,则不会产生参数构造的成本。另一方面,如果为DEBUG级别启用了记录器,则会产生两次评估记录器是否启用的成本:一次debugEnabled
一次,一次在debug
。实际上,此开销微不足道,因为评估记录器所花费的时间不到实际记录请求所需时间的 1%。
使用大括号语法(在手册中不久之后提供(通常是一个很好的折衷方案,我真的很喜欢它,因为它有助于区分正在记录的语句和进入其中的数据。但是,如果未启用日志级别,则与完全跳过并不完全相同,因为参数仍会进行评估并传递给日志记录系统,然后才能确定是否需要记录它们。