SLF4J设为WARN级别时,debug语句及其中耗时方法是否会执行?
SLF4J日志级别设置为WARN时的两个关键问题解答
1. 设置WARN级别会阻止logger.debug(...)语句执行吗?
简单说:日志输出会被阻止,但debug()方法本身还是会被调用。
SLF4J的日志方法内部会先检查当前配置的日志级别,如果级别低于设定值(比如WARN优先级比DEBUG高),就会跳过日志消息的格式化和输出步骤,但方法本身的调用流程还是会走一遍——只是最后没有产生实际的日志输出而已。
2. 日志参数里的耗时方法会被执行吗?
这才是你最关心的核心问题:会执行!而且是在debug()方法调用前就已经执行了。
Java的方法参数遵循「求值优先」原则,也就是说,当你写下这段代码时:
logger.debug("hello i am a log line not so neccessary, also log level is setted WARN and some complexProcessResult-> {}", doSomeWorkwhichTakeslongTime());
JVM会先运行doSomeWorkwhichTakeslongTime()得到返回结果,再把这个结果作为参数传给debug()方法。等debug()方法内部检查到当前级别是WARN、不需要输出日志时,那个耗时方法早就跑完了,时间已经白白浪费掉。
怎么避免这种不必要的耗时?
有两种可靠的解决方案:
- 手动检查日志级别:在调用debug方法前先判断是否开启了DEBUG级别,没开启就直接跳过耗时操作:
if (logger.isDebugEnabled()) { String complexResult = doSomeWorkwhichTakeslongTime(); logger.debug("hello i am a log line not so neccessary..., {}", complexResult); } - 使用SLF4J的Supplier API(Java 8+):SLF4J 1.8.0及以上版本支持Supplier参数,只有当日志级别允许输出时,才会触发Supplier的
get()方法:
这里的lambda表达式logger.debug("hello i am a log line not so neccessary..., {}", () -> doSomeWorkwhichTakeslongTime());() -> doSomeWorkwhichTakeslongTime()只有在DEBUG级别开启时才会执行,完美避免了非DEBUG环境下的耗时计算。
总结
仅把日志级别设为WARN不足以阻止那个耗时方法的执行,必须配合上面两种方法之一,才能在生产环境(非DEBUG级别)下跳过不必要的耗时操作。
内容的提问来源于stack exchange,提问作者user2602041
相关产品推荐
相关产品推荐

