Eclipse-声纳S2629可能与新字符串误报



我使用的是最新的Eclipse和Sonar插件

日志记录的答案是:

log.debug("Request body: {}", new String(body, "UTF-8"));

只有在调试级别时才应该创建字符串:

/**
* Log a message at the DEBUG level according to the specified format
* and argument.
* <p/>
* <p>This form avoids superfluous object creation when the logger
* is disabled for the DEBUG level. </p>
*
* @param format the format string
* @param arg    the argument
*/
public void debug(String format, Object arg);

但Sonar将其标记为squid:S2629:

"前提条件"和日志参数不应要求评估(squid:S2269(

并举例说明级联

logger.log(Level.DEBUG,"出现问题:"+消息(;//不合规的;即使在日志级别过高而无法显示调试消息时也执行字符串串联

这是误报声纳警告还是我遗漏了什么?

这不是这个问题的重复,这个问题通常是关于规则概念的,它是串联的,但不是用创建对象作为new String来格式化

另一个答案的链接说,创建new Date()并没有产生内置格式的问题:

public static void main(String[] args) {
LOGGER.info("The program started at {}", new Date());
}
}

通过这种方式进行日志记录,可以避免在不应该实际记录任何内容的情况下串接的性能开销。

在非调试模式下,行

log.debug("Request body: {}", new String(body, "UTF-8"));

而不是

log.debug(MessageFormatter.format("Request body: {}", new String(body, "UTF-8")));

避免创建通过MessageFormatter.format(String messagePattern, Object arg)创建的字符串,但不创建通过new String(body, "UTF-8")创建的其他字符串。

这意味着它不是一个假阳性,因为参数是在调用日志记录方法之前首先计算的。

只要SLF4J不支持lambda表达式延迟求值参数,就可以使用以下实用程序方法作为解决方法:

private static Object lazyToString(final Supplier<String> stringSupplier) {
return new Object() {
@Override
public String toString() {
return stringSupplier.get();
}
};
}

这可以用于将字节数组转换为字符串限制为仅DEBUG模式:

log.debug("Request body: {}", lazyToString(() -> new String(body, StandardCharsets.UTF_8)));

虽然lambda或lazy lambda的使用很好,但仍然有好的旧isDebugEnabled方法:

if (log.isDebugEnabled()) {
log.debug("Request body: {}", new String(body, StandardCharsets.UTF_8));
}

这不会修复正在创建的String(因为您毕竟想显示它(,但在禁用调试模式时不会消耗内存。

相关内容

  • 没有找到相关文章

最新更新