日志写入方法中的 Sonarlint 投诉
Sonarlint complaint in log writting method
log.info(String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms))
Sonarlint 显示以下错误:
"Preconditions" and logging arguments should not require evaluation
Compliant Solution:
logger.log(Level.SEVERE, "Something went wrong: {0} ", message);
让我们试试看:
log.info("Execution of method {0} finished in {1} ms", pointcut.getSignature().getName(), ms);
Printf-style format strings should be used correctly
Compliant Solution:
String.format("First %s and then %s", "foo", "bar");
我觉得 sonarlint 只是在嘲笑我。
这是我对他的判断,但我真的不明白发生了什么事或他为什么首先抱怨:
String logMessage = String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms);
log.info(logMessage);
有什么想法吗?
- 在带有 {} 的第一个版本中,{} 的 type 在 runtime 时评估。
- 在第二个 %s、%d 中,您在 编译时 定义了 类型。
如果可能,您应该使用类型来避免滥用占位符变量,并允许 java 编译器进行一些额外的检查。
I don't really understand whats going or why he complaints in the first place:
第一个示例中的投诉原因是您无条件地 做大量工作来构建日志消息。如果日志级别高于 INFO,则工作将被浪费。
第二个示例比第一个要好,因为日志消息字符串仅在日志级别为 INFO 或更低时从模板创建。 pointcut.getSignature().getName()
表达式仍然是无条件计算的,但这可能是不可避免的,具体取决于您使用的特定日志记录 API。
(如果计算成本很高,你仍然有性能问题。你可以考虑使用 if (log.isInfoLevel()) { ... }
守卫,或者使表达式计算变得惰性的东西;例如 Supplier<String>
。但是最好的解决方案可能是避免记录那个昂贵的表达式。)
第二个示例中的 Sonar 投诉似乎与您在消息/格式字符串中使用的特定语法有关。 @C.Lechner 的回答是这样解释的:
- In the first version with {} the type of {} is evaluated at runtime.
- In the 2nd with %s, %d you define the type at compile time.
If possible you should use a type to avoid misuse of placeholder
variables and allow java compiler to do some additional checks.
我不完全相信 Java 编译器会进行检查。 (JLS 当然不需要。)但是编译器或(智能)静态代码分析器可以检查肯定是合理的。
无论哪种方式,都会在运行时(再次)检查格式字符串。
最后,这个版本:
String logMessage = String.format("Execution of method %s finished in %d ms",
pointcut.getSignature().getName(), ms);
log.info(logMessage);
与第一个版本有相同的性能问题,但我怀疑 Sonar 不够聪明,无法解决这个问题。
log.info(String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms))
Sonarlint 显示以下错误:
"Preconditions" and logging arguments should not require evaluation
Compliant Solution:
logger.log(Level.SEVERE, "Something went wrong: {0} ", message);
让我们试试看:
log.info("Execution of method {0} finished in {1} ms", pointcut.getSignature().getName(), ms);
Printf-style format strings should be used correctly
Compliant Solution:
String.format("First %s and then %s", "foo", "bar");
我觉得 sonarlint 只是在嘲笑我。
这是我对他的判断,但我真的不明白发生了什么事或他为什么首先抱怨:
String logMessage = String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms);
log.info(logMessage);
有什么想法吗?
- 在带有 {} 的第一个版本中,{} 的 type 在 runtime 时评估。
- 在第二个 %s、%d 中,您在 编译时 定义了 类型。
如果可能,您应该使用类型来避免滥用占位符变量,并允许 java 编译器进行一些额外的检查。
I don't really understand whats going or why he complaints in the first place:
第一个示例中的投诉原因是您无条件地 做大量工作来构建日志消息。如果日志级别高于 INFO,则工作将被浪费。
第二个示例比第一个要好,因为日志消息字符串仅在日志级别为 INFO 或更低时从模板创建。 pointcut.getSignature().getName()
表达式仍然是无条件计算的,但这可能是不可避免的,具体取决于您使用的特定日志记录 API。
(如果计算成本很高,你仍然有性能问题。你可以考虑使用 if (log.isInfoLevel()) { ... }
守卫,或者使表达式计算变得惰性的东西;例如 Supplier<String>
。但是最好的解决方案可能是避免记录那个昂贵的表达式。)
第二个示例中的 Sonar 投诉似乎与您在消息/格式字符串中使用的特定语法有关。 @C.Lechner 的回答是这样解释的:
- In the first version with {} the type of {} is evaluated at runtime.
- In the 2nd with %s, %d you define the type at compile time.
If possible you should use a type to avoid misuse of placeholder variables and allow java compiler to do some additional checks.
我不完全相信 Java 编译器会进行检查。 (JLS 当然不需要。)但是编译器或(智能)静态代码分析器可以检查肯定是合理的。
无论哪种方式,都会在运行时(再次)检查格式字符串。
最后,这个版本:
String logMessage = String.format("Execution of method %s finished in %d ms",
pointcut.getSignature().getName(), ms);
log.info(logMessage);
与第一个版本有相同的性能问题,但我怀疑 Sonar 不够聪明,无法解决这个问题。