SonarQube提示:为何Java日志参数方法未按级别条件执行?
日志方法参数执行问题解析与解决
为什么会出现两次"Did additional work..."?
Java的方法调用逻辑是先计算所有参数表达式,再调用目标方法。哪怕log.debug()的日志级别没达标,JVM也会先执行additional()方法拿到返回值,再把值传给log.debug()——这就导致additional()里的日志被打印了一次。加上log.info()那次执行的additional(),最终就出现了两次输出。你的默认日志级别是INFO,所以log.debug()本身的日志没输出,但参数方法已经跑完了。
解决办法
方法1:手动判断日志级别
先检查当前日志级别是否允许输出,再执行带副作用的方法:
public void runDebug() { if (log.isDebugEnabled()) { log.debug("hello @ debug {}", additional()); } }
只有当DEBUG级别开启时,才会触发additional()和日志打印。
方法2:用SLF4J的Lambda延迟加载
SLF4J 2.0及以上版本支持传入Supplier类型参数,它会在日志级别符合要求时才执行Supplier的逻辑:
public void runDebug() { log.debug("hello @ debug {}", () -> additional()); }
这种写法更简洁,底层会自动做级别判断,避免不必要的方法执行。
关于SonarQube的提示
SonarQube标记的"Invoke method(s) only conditionally"就是在提醒你:这类有副作用(比如打印日志、耗时操作)的方法不能无条件作为日志参数,否则不管日志级别如何都会执行,可能造成性能浪费或意外行为,上面两种方案都能解决这个问题。
内容的提问来源于stack exchange,提问作者Patrick Rode
相关产品推荐
相关产品推荐

