使用 SLF4J 记录异常时 Sonarcloud 发出警报 "not enough arguments"

Sonarcloud alerts "not enough arguments" when logging exceptions using SLF4J

我在 Java 中管理一个开源项目,在我的代码中有大约 20 个地方使用以下模式记录异常(slf4j 版本 1.7.30)

private static final Logger logger = LoggerFactory.getLogger();

... 

try {
  interfaces = NetworkInterface.getNetworkInterfaces(); 
} catch (SocketException ex) {
  logger.error("Socket exception when retrieving interfaces: {}", ex);
}

或类似的

try {
  // stuff
} catch (IOException ioe) {
  logger.error("Server error: {}", ioe);
}

从今天开始,带有特定消息 "Not enough arguments."

SonarCloud automated code quality review has begun flagging these with rule java:S2275(Printf 样式格式字符串不应在运行时导致意外行为)

编辑:值得注意的是,当 Exception 是最后一个参数时,这似乎总是发生。以下模式 标志:

try {
  // Server connection code
} catch (IOException e) {
  logger.error("Server Connection error: {}", e.getMessage());
}

this other Whosebug question 的评论表明,也许异常的额外参数是可选的,并且会导致不同的行为,所以我不清楚它在这里如何应用以及为什么它会突然改变。

我 can/should 是否做了一些事情来更好地将这些异常转换为日志消息(例如,对所有异常使用 getMessage() 而不是依赖自动 toString() 解析),还是误报?

(Sonar 列出我的 20 个问题 linked here。)

这纯属猜测,但每个问题都指向一个日志行,可以概括为:

LOG.something(format, custom_arguments, exception)

其中格式有 {} 出现 count(custom_arguments) + 1(为例外保留的 1)。

如您所见 linked answer,slf4j 对异常进行了特殊处理,因此可能由于某种原因 SonarCloud 正在做同样的事情。不幸的是没有文档。

"fix" 将删除用于异常的最终 {},例如

LOG.error("boom: {}", e);
LOG.error("boom2 {}: {}", something, e);

变成

// exceptions handled in a special way
LOG.error("boom", e);
LOG.error("boom2 {}", something, e);