[日志] 打印异常堆栈信息的技巧
序
-
Java的异常堆栈信息,对提升排查问题的效率,有极大的帮助————便于我们快速定位异常的发生过程和发生异常的代码行。
-
本文使用的日志框架
- slf4j : 1.7.25
- log4j(2) : 2.20.0
- 日志行的打印策略 :
log4j2.properties
# property.log.layout.consolePattern=%d{yyyy/MM/dd HH:mm:ss.SSS} %-5p | %T | %t | (%C{1}.java:%L %M) | %m%n
# property.log.layout.consolePattern=[%d{yyyy/MM/dd HH:mm:ss.SSS}] [%traceId] [%-5p] [%t] [%C{1}.java:%L %M] %m%n
#property.log.layout.consolePattern=[%d{yyyy/MM/dd HH:mm:ss.SSS}] [%X{traceId}] [%-5p] [%t] [%C{1}.java:%L %M] %m%n
property.log.layout.consolePattern=[%traceId] [${application.name}] [system] [%d{yyyy/MM/dd HH:mm:ss.SSS}] [%-5p] [%t] [%C{1}] %M:%L__|%X{traceId}|__%m%n
#property.log.layout.mainPattern=[${application.name}] [${instance.name}] [${env:HOST_IP}] [${env:CONTAINER_IP}] [%d{yyyy/MM/dd HH:mm:ss.SSS}] [%p] [%t] [%l] %m%n
...
# console
# 指定输出源的类型与名称
appender.console.type=Console
appender.console.name=CONSOLE_APPENDER
#appender.console.layout.type=PatternLayout
appender.console.layout.type=CustomPatternLayout
appender.console.layout.pattern=${log.layout.consolePattern}
...
打印异常堆栈信息的技巧
错误示范
- 错误的关键:不应该使用
{}
符
package xxx.yyy.zzz;
//import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//@Slf4j
public class Demo {
private static final Logger log = LoggerFactory.getLogger(Demo.class);
public static void main(String[] args) {
try {
test();
} catch (Exception exception) {
log.info("exception.message:{}\nexception:{}", exception.getMessage(), exception);
}
}
public static void test(){
System.out.println("hello");
throw new RuntimeException("Xxxx abnormal!");
}
}
运行效果: 未打印出堆栈信息
hello
[TID: N/A] [my-app-service] [system] [2025/01/22 18:07:37.956] [INFO ] [main] [Demo] main:16__||__exception.message:Xxxx abnormal!
exception:java.lang.RuntimeException: Xxxx abnormal!
正确示范
- 正确的关键:想打印出堆栈,就不要使用
{}
符
package xxx.yyy.zzz;
//import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//@Slf4j
public class Demo {
private static final Logger log = LoggerFactory.getLogger(Demo.class);
public static void main(String[] args) {
try {
test();
} catch (Exception exception) {
log.info("exception.message:{}\nexception:", exception.getMessage(), exception);
}
}
public static void test(){
System.out.println("hello");
throw new RuntimeException("Xxxx abnormal!");
}
}
运行效果: 打印出了堆栈信息
hello
[TID: N/A] [my-app-service] [system] [2025/01/22 18:09:41.949] [INFO ] [main] [Demo] main:16__||__exception.message:Xxxx abnormal!
exception:
java.lang.RuntimeException: Xxxx abnormal!
at xxx.yyy.zzz.Demo.test(Demo.java:22) ~[classes/:?]
at xxx.yyy.zzz.Demo.main(Demo.java:14) [classes/:?]
场景延伸:String.format(xxx, exception)
- 同样需求,
String.format(xxx, exception)
的表现如何呢?
- 错误示范
public static void main(String[] args) {
try {
throw new RuntimeException("hello\n3535329rew8g8723tr8gsi\nwerewfds");
} catch (Exception exception) {
logger.info(String.format("exception:", exception));
}
}
out
exception:
- 正确示范
public static void main(String[] args) {
try {
throw new RuntimeException("hello\n3535329rew8g8723tr8gsi\nwerewfds");
} catch (Exception exception) {
logger.info(String.format("exception:%s", exception));//重点:`%s`
}
}
out
exception:
3535329rew8g8723tr8gsi
werewfds

本文作者:
千千寰宇
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!