0

我在我们的项目中使用 logback。我已经浏览了花括号的 logback 链接。

logger.debug(" My class output value - {}, object toString() {}", object.value(), object.toString());

我的项目中未启用调试。我们看到 toString() 在我们的项目中被调用,这会影响我们的性能。在禁用调试的代码执行期间是否会调用 toString()?

我可以用这种方法使用 toString() 吗?因为根据花括号定义字符串 concat 不会发生。它仅适用于字符串 concat 还是也适用于方法调用?

4

2 回答 2

1

Logback 并没有改变 Java 的规则:当你调用一个方法时,方法的参数需要被计算才能被传递给方法。当未启用日志级别时,使用花括号表示法所节省的只是 String concatenation的成本,也就是说,构建要从各个组件记录的完整 String 的成本。

如果评估参数的成本显着降低了您的性能,使其不再满足客户的需求,那么您可能希望避免在未启用日志级别的情况下运行它的成本。来自 Logback 手册,第 2 章:架构,“参数化日志记录”:

避免参数构造成本的一种可能方法是用测试包围日志语句。这是一个例子。

if(logger.isDebugEnabled()) { 
   logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}

这样,如果对logger. 另一方面,如果在 DEBUG 级别启用了记录器,您将承担两次评估记录器是否启用的成本:一次进入debugEnabled和一次进入debug。实际上,这种开销是微不足道的,因为评估记录器所花费的时间不到实际记录请求所需时间的 1%。

使用花括号语法(在手册中稍后介绍)通常是一个很好的折衷方案,我真的更喜欢它,因为它有助于区分正在记录的语句和进入其中的数据。但是,如果您的日志级别未启用,则它与完全跳过并不完全相同,因为参数仍会被评估并传递给日志系统,然后才能确定是否需要记录它们。

于 2018-05-03T20:01:13.117 回答
1

从 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() 开销。

于 2018-05-03T17:34:51.023 回答