我想禁止这样的代码:
private static final Logger LOGGER = LogManager.getLogger(...)
...
...
LOGGER.info("User(%s) not found.", userId);
最好这样做:
LOGGER.info("User({}) not found.", userId);
如何配置 checkstyle 来捕获这些错误?
可能没有标准检查来禁止这种情况(至少在官方页面)。
对于 99% 的情况,以下基于正则表达式 (RegexpSingleLineJava) 的自定义检查将起作用:
<module name="RegexpSinglelineJava">
<property name="format" value="(LOGGER|LOG|logger|log)\.[a-z]+\(.*%s"/>
<property name="ignoreComments" value="true"/>
<property name="message" value="Formatting with %s in Log4J log strings is not allowed, use {} instead" />
</module>
正则表达式定位一个记录器,后跟一个点、多个字母(即
info
、warn
、error
等)、左大括号和一些任意字符后的 %s
。评论被忽略。
限制:
%s
与 LOGGER
不在同一行,checkstyle 不会捕获错误(但是,格式字符串通常与 LOGGER
位于同一行,与参数不同);(LOGGER|LOG|logger|log)
),checkstyle不会捕获错误;LOGGER.warn("This is an extremely awful code style."); String str = String.format("%s", "someText");
编写自定义 Checkstyle 检查可能有助于克服这些限制,但我不确定在实际项目中是否值得。 如果目标是告诉您的开发人员停止在日志中使用
%s
,而不是查找这种情况的每一次出现,那么使用单行正则表达式检查应该完全没问题。
如果你也可以使用SpotBugs(FindBugs的后继者),你可以尝试一下https://github.com/eller86/findbugs-slf4j.
示例:
// invalid: format is not CONST
String format = new String("Hello, ");
logger.info(format + "{}.", "World");
// valid
logger.info("Hello, {}.", "World");
它还检查其他模式。