Slf4j打印异常的堆栈信息
一、前言
直接用logger.info("异常信息为:"+e)或者logger.info(e.getMessage())只能记录到异常的描述信息,却没有其异常具体发生在哪一行代码。
这样即使通过日志发现出现了异常,也没法马上定位问题。
因此就催生了一个想法,打印日志是否能像在IDE本地跑程序时出现未捕获的异常时,控制台能打印出完整的错误堆栈信息。
二、问题场景
日常开发中,经常在service实现层使用try-catch-finally保证代码的健壮性, 直接用logger.info("异常信息为:"+e)或者logger.info(e.getMessage())只能记录到异常的描述信息,无法打印完整异常堆栈信息,无法定位其异常具体发生在哪一行代码,当面对比较复杂的代码,那么排查问题将会非常麻烦。
下文将简单重现这类场景,并得到相应的解决方法。
1、不加try-catch
示例:
@GetMapping("/hello")
public String sayHello(){
logger.info("hello Sfl4j + logback......");
int i = 3/0;
return helloService.sayHello();
}
运行结果:

即:当不加try-catch的时候,当出现了意料之外的运行时异常,控制台是能够能打印出完整的错误信息。
2、加上try-catch
示例:
@GetMapping("/hello")
public String sayHello(){
logger.info("hello Sfl4j + logback......");
try{
int i = 3/0;
}catch (Exception e){
logger.info("计算出错1:"+e);
logger.info("计算出错2:"+e.getMessage());
}
return helloService.sayHello();
}
运行结果:

即:try-catch代码中使用logger.info("异常信息为:"+e)或者logger.info(e.getMessage()),只能打印异常描述信息,无法打印异常堆栈,无法定位具体出错位置。
三、解决方法
--->打印出完整的异常堆栈信息方法
方法1:e.printStackTrace();
示例:
@GetMapping("/hello")
public String sayHello(){
logger.info("hello Sfl4j + logback......");
try{
int i = 3/0;
}catch (Exception e){
e.printStackTrace();
}
return helloService.sayHello();
}
运行结果:

注:
这种方式很占内存空间,尤其生产环境不能过多使用。
并且这种方式只是控制台打印,日志文件中不打印。
方法2:
logger.error(String msg, Throwable t);------>logger.error(e.getMessage(),e);
或者
logger.info(String msg, Throwable t);------>logger.info(e.getMessage(),e);
示例:
@GetMapping("/hello")
public String sayHello(){
logger.info("hello Sfl4j + logback......");
try{
int i = 3/0;
}catch (Exception e){
logger.error(e.getMessage(),e);
// logger.info(e.getMessage(),e);
}
return helloService.sayHello();
}
运行结果:

使用扩展:
如果msg含有变量,SLF4J 1.6.0之前版本一般用String.format方法格式化msg。
SLF4J 1.6.0版本之后,
error(String format, Object... arguments)
info(String format, Object... arguments)
方法也会打印异常堆栈信息,只不过规定Throwable对象必须为最后一个参数.如果不遵守这个规定,异常堆栈信息不会打印出来。
官网示例:
String s = "Hello world";
try {
Integer i = Integer.valueOf(s);
} catch (NumberFormatException e) {
logger.error("Failed to format {}", s, e);
}
使用示例:
@GetMapping("/hello")
public String sayHello(){
logger.info("hello Sfl4j + logback......");
try{
int i=3/0;
}catch(Exception e){
logger.error("错误消息:{}",e.getMessage(),e);
}
return helloService.sayHello();
}
}
运行示例:

小结:
1、Slf4j打印异常堆栈信息使用:
logger.error(String msg, Throwable t);------>logger.error(e.getMessage(),e);
或者
logger.info(String msg, Throwable t);------>logger.info(e.getMessage(),e);
规范示例:
logger.error("错误消息:{}",e.getMessage(),e);
2、异常信息Exception e 的相关方法
- e.toString():获得异常类型和错误信息描述
- e.getMessage():获得错误信息描述
- e.printStackTrace():在控制台打印出异常堆栈(异常类型、错误信息描述和出错位置等)。
Slf4j打印异常的堆栈信息的更多相关文章
- JAVA将异常的堆栈信息转成String
有时候我们需要将系统出现异常的堆栈信息显示到异常页面的一个隐藏的DIV内,这样查看源时就可以快速的定位到异常信息.这个时候就要将异常信息转成String. /* * 将异常的堆栈信息转成String ...
- Java异常---获取异常的堆栈信息
Java 实例 - 获取异常的堆栈信息 Java 实例 以下实例演示了使用异常类的 printStack() 方法来获取堆栈信息: Main.java 文件 public class Main{ p ...
- Java如何打印异常的堆栈?
在Java编程中,如何打印异常的堆栈? 此示例显示如何使用异常类的printStack()方法打印异常的堆栈. package com.yiibai; public class PrintStackT ...
- 利用Xposed Hook打印Java函数调用堆栈信息的几种方法
本文博客链接:http://blog.csdn.net/QQ1084283172/article/details/79378374 在进行Android逆向分析的时候,经常需要进行动态调试栈回溯,查看 ...
- 在java中捕获异常时,使用log4j打印出错误堆栈信息
当java捕获到异常时,把详细的堆栈信息打印出来有助于我们排查异常原因,并修复相关bug,比如下面两张图,是打印未打印堆栈信息和打印堆栈信息的对比: 那么在使用log4j输出日志时,使用org.apa ...
- 使用linux backtrace打印出错函数堆栈信息
一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...
- Logger.error方法之打印错误异常的详细堆栈信息
一.问题场景 使用Logger.error方法时只能打印出异常类型,无法打印出详细的堆栈信息,使得定位问题变得困难和不方便. 二.先放出结论 Logger类下有多个不同的error方法,根据传入参数的 ...
- 打印Java异常堆栈信息
背景 在开发Java应用程序的时候,遇到程序抛异常,我们通常会把抛异常时的运行时环境保存下来(写到日志文件或者在控制台中打印出来).这样方便后续定位问题. 需要记录的运行时环境包含两部分内容:抛异常时 ...
- log4j打印错误异常的详细堆栈信息
一.问题场景 使用Logger.error方法时只能打印出异常类型,无法打印出详细的堆栈信息,使得定位问题变得困难和不方便. 二.先放出结论 Logger类下有多个不同的error方法,根据传入参数的 ...
随机推荐
- ubuntu14 安装tftp服务器
安装 sudo apt-get install tftp-hpa tftpd-hpa 配置 sudo gedit /etc/default/tftpd-hpa 打开tftpd-hpa修改里面的配置: ...
- 【转载】MDX Step by Step 读书笔记(三) - Understanding Tuples (理解元组)
1. 在 Analysis Service 分析服务中,Cube (多维数据集) 是以一个多维数据空间来呈现的.在Cube 中,每一个纬度的属性层次结构都形成了一个轴.沿着这个轴,在属性层次结构上的每 ...
- [性能测试]:关于MQ协议脚本开发
消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们. 银行脚本使用MQ通信的较多,下面介绍一个MQ的脚本: M ...
- es6里class类
/** * Created by issuser on 2018/11/27. *///如果静态方法包含this关键字,这个this指的是类,而不是实例./** (1)类的实例属性 1.类的实例属性可 ...
- vs2010 编译 boost1.65.1
vs2010编译boos1.65.1注意选项 vs2010 不支持 c99 ,string.c和debugger.c 变量定义顺序位置报错,改变顺序即可. debugger.c va_copy 在c8 ...
- Hibernate3.3.2_JUnit_BoforeClass不报异常的Bug处理
假如你把配置文件写错了,myeclipse竟然不报错,只说sf空指针. <mapping class="com.oracle.hibernate.model."/> / ...
- 微服务Kong(五)——添加一个用户(Consumer)
在本节中,我们将学习如何添加一个用户(consumer)到KONG实例中.用户是与使用您的API的个人相关联,可用于跟踪,访问管理等. NOTE:本节假设您已经正确启用了密钥验证插件.如果没有,请参考 ...
- ubuntu 16.04安装好后没声音的解决方法
刚安装好Ubuntu16.04 后没声音,找了好多方法都不行,看到网上说通过安装pavucontrol和alsamixer调节解决,最后无意发现一个方法,总算是可以用了,在此记录一下.可能有的可以解决 ...
- 2-9 js基础 cookie封装
// JavaScript Document 'use strict'; function setCookie(sName,sValue,iDay){ if(iDay){ var oDate = ne ...
- hadoop开发环境
hadoop2.6伪分布式环境安装配置以及配置eclipse开发环境 Hadoop安装教程_单机/伪分布式配_Hadoop2.6.0/Ubuntu14.04 使用Eclipse编译运行MapReduc ...