使用Logger.error("msg",e)未打印堆栈追踪的原因及解决方法
为何使用Logger.error("msg", e)时未打印堆栈追踪?
使用环境
日志框架:org.slf4j 1.7.26、logback 1.2.3
问题场景
场景1
try{ …… }catch(Exception e){ …… logger.error(String.format("deliverTask error:%s",e.getMessage()),e); }
日志输出:
deliverTask error:null
场景2
try{ …… }catch(Exception e){ …… logger.error(String.format("deliverTask error:%s",e.toString()),e); }
日志输出:
deliverTask error:java.lang.NullPointerException
原因分析
- 日志格式配置缺失:logback的日志输出Pattern未包含异常堆栈的占位符(如
%ex或%stackTrace)。如果配置文件里的<pattern>仅定义了时间、级别、消息等基础内容,没有添加堆栈输出项,即便传入异常对象,也只会输出消息文本,不会打印堆栈信息。 - 手动拼接消息不影响堆栈输出逻辑:你调用的是
logger.error(String, Throwable)重载方法,已经正确传入了异常对象,但堆栈是否输出完全由logback的格式配置决定,和你用String.format拼接消息内容无关。
解决方法
1. 修改logback配置文件的日志格式
在logback.xml或logback.groovy中,确保日志Pattern包含%ex(输出完整堆栈)或%xEx(输出精简堆栈)。示例配置:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%ex</pattern> </encoder> </appender>
其中%n%ex表示在日志消息换行后,输出完整的异常堆栈信息。
2. 简化日志调用逻辑
无需手动拼接异常信息,直接利用日志框架的模板功能传递参数,避免e.getMessage()为null的情况:
// 方式1:传递消息模板和异常 logger.error("deliverTask error:{}", e.getMessage(), e); // 方式2:直接传入消息和异常,日志框架会自动处理异常的描述和堆栈 logger.error("deliverTask error", e);
内容的提问来源于stack exchange,提问作者ShawnChen
相关产品推荐
相关产品推荐

