Log4j2 的 PatternLayout 默认不打印 root cause,需用 %xEx{root} 显式输出最内层异常堆栈;%xEx{full} 输出完整异常链,%xEx{short} 仅输出首异常简略信息,%throwable 不支持 root-only 模式。

Log4j2 的 PatternLayout 默认不会完整打印异常链中的 root cause(即最底层的根本异常),它通常只输出第一个异常及其堆栈。要让日志中清晰呈现 root cause(比如 NullPointerException 而不是外层包装的 RuntimeException),需借助 %xEx 或 %throwable 的增强参数,配合自定义 Pattern 实现。
使用 %xEx{full} 显式输出带 root cause 的完整异常
%xEx 是 Log4j2 提供的扩展异常格式器,支持递归展开整个异常链,并可配置是否显示 root cause。推荐在 Pattern 中使用:
-
%xEx{full}:输出全部异常(包括 cause 链),按从外到内顺序,每层都带完整堆栈 -
%xEx{root}:仅输出 root cause(最内层异常)及其堆栈,跳过中间包装异常 -
%xEx{short}:只输出第一个异常的简略信息(不含 cause)
示例 Pattern(XML 配置):
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %c{1} - %msg%xEx{root}%n"/>在 properties 文件中配置 PatternLayout
若使用 log4j2.properties,写法类似:
立即学习“Java免费学习笔记(深入)”;
注意:%xEx{root} 会单独打印 root cause 的完整堆栈(含类名、消息、行号),不与主异常混在一起,可读性高。如果希望把 root cause 行内显示(如只显示异常类型+消息),可用 %xEx{root, short}。
避免用 %throwable 替代 —— 它不支持 root-only 模式
%throwable 是传统写法,等价于 %xEx{full},但无法指定只输出 root cause。它总是打印整个异常链,且格式固定、不可定制。若业务中大量使用 RuntimeException 包装底层异常(如 Spring 的 DataAccessException),直接用 %throwable 会导致日志冗长、关键 root cause 被淹没。此时 %xEx{root} 更精准。
验证 root cause 是否生效的小技巧
写一段测试代码主动抛出嵌套异常:
throw new RuntimeException("outer", new IllegalArgumentException("inner", new NullPointerException("null ref")));观察日志输出:若看到 java.lang.NullPointerException: null ref 及其堆栈,说明 %xEx{root} 配置成功;若只看到 RuntimeException,检查 Pattern 中是否误写为 %throwable 或漏掉 {root} 参数。



















