使用 SLF4J 记录异常时,Sonarcloud 会警告“没有足够的参数”

Dan*_*dis 2 java slf4j exception-logging sonarcloud

我用 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);
}
Run Code Online (Sandbox Code Playgroud)

或类似

try {
  // stuff
} catch (IOException ioe) {
  logger.error("Server error: {}", ioe);
}
Run Code Online (Sandbox Code Playgroud)

从今天开始,SonarCloud自动代码质量审查已开始使用规则标记这些java:S2275(Printf 样式的格式字符串不应导致运行时出现意外行为),并带有特定消息“参数不足”。

编辑:值得注意的是,当 anException是最后一个参数时,这似乎总是发生。下面的模式确实没有标志:

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

另一个 StackOverflow 问题的回顾表明,异常的额外参数可能是可选的,并且会导致不同的行为,所以我不清楚这将如何应用于这里以及它为什么会突然改变。

我可以/应该做些什么来更好地将这些异常转换为日志消息(例如,getMessage()在所有这些异常上使用而不是依赖自动toString()解析),还是这是误报?

(Sonar 列出了我在此处链接的20 个问题。)

Ada*_*ski 7

这纯粹是猜测,但每个问题都指向一条日志线,可以概括为:

LOG.something(format, custom_arguments, exception)
Run Code Online (Sandbox Code Playgroud)

其中{}出现格式count(custom_arguments) + 1(1 保留用于例外)。

正如您所看到的链接答案,slf4j 会特别处理异常,因此可能由于某种原因 SonarCloud 正在做同样的事情。不幸的是,没有文档。

“修复”将删除{}用于异常的最终目的,例如

LOG.error("boom: {}", e);
LOG.error("boom2 {}: {}", something, e);
Run Code Online (Sandbox Code Playgroud)

变成

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

  • 好的,做了一些测试,虽然不明显/没有记录,但根据您的示例删除 {} 时,行为是相同的。看来声纳最近可能改变了他们的检查更加严格。 (2认同)