一、前言

  直接用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打印异常的堆栈信息的更多相关文章

  1. JAVA将异常的堆栈信息转成String

    有时候我们需要将系统出现异常的堆栈信息显示到异常页面的一个隐藏的DIV内,这样查看源时就可以快速的定位到异常信息.这个时候就要将异常信息转成String. /* * 将异常的堆栈信息转成String ...

  2. Java异常---获取异常的堆栈信息

    Java 实例 - 获取异常的堆栈信息  Java 实例 以下实例演示了使用异常类的 printStack() 方法来获取堆栈信息: Main.java 文件 public class Main{ p ...

  3. Java如何打印异常的堆栈?

    在Java编程中,如何打印异常的堆栈? 此示例显示如何使用异常类的printStack()方法打印异常的堆栈. package com.yiibai; public class PrintStackT ...

  4. 利用Xposed Hook打印Java函数调用堆栈信息的几种方法

    本文博客链接:http://blog.csdn.net/QQ1084283172/article/details/79378374 在进行Android逆向分析的时候,经常需要进行动态调试栈回溯,查看 ...

  5. 在java中捕获异常时,使用log4j打印出错误堆栈信息

    当java捕获到异常时,把详细的堆栈信息打印出来有助于我们排查异常原因,并修复相关bug,比如下面两张图,是打印未打印堆栈信息和打印堆栈信息的对比: 那么在使用log4j输出日志时,使用org.apa ...

  6. 使用linux backtrace打印出错函数堆栈信息

    一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...

  7. Logger.error方法之打印错误异常的详细堆栈信息

    一.问题场景 使用Logger.error方法时只能打印出异常类型,无法打印出详细的堆栈信息,使得定位问题变得困难和不方便. 二.先放出结论 Logger类下有多个不同的error方法,根据传入参数的 ...

  8. 打印Java异常堆栈信息

    背景 在开发Java应用程序的时候,遇到程序抛异常,我们通常会把抛异常时的运行时环境保存下来(写到日志文件或者在控制台中打印出来).这样方便后续定位问题. 需要记录的运行时环境包含两部分内容:抛异常时 ...

  9. log4j打印错误异常的详细堆栈信息

    一.问题场景 使用Logger.error方法时只能打印出异常类型,无法打印出详细的堆栈信息,使得定位问题变得困难和不方便. 二.先放出结论 Logger类下有多个不同的error方法,根据传入参数的 ...

随机推荐

  1. 如何在ASP.NET Core 2.0中使用Razor页面

    如何在ASP.NET Core 2.0中使用Razor页面  DotNetCore2017-11-22 14:49 问题 如何在ASP.NET Core 2.0中使用Razor页面 解 创建一个空的项 ...

  2. 持续集成篇:jenkins搭建和job运行

    好久没有更博了,最近都在忙着其他事情,年底前加上这章再更5篇,10月份开始因为公司业务,要接触appium啦,之后应该也会有所分享. Jenkins所需环境  硬件需求: ①至少需要有256M内存,推 ...

  3. 对 云寻觅贴吧(http://tieba.yunxunmi.com/)的简要分析

    1. 云寻觅的用户需求:一方面是很多用户有很多问题,需要高质量的答案,但是搜索引擎无法满足这种需求,百度知道做得不够好,所以用户需要一个平台可以解决他们的问题:另外一方面,又有很多经济良好,时间较为充 ...

  4. redis持久化之 aof日志

    aof就是把执行的命令写到文本文件里面 aof使用过程 第一步: 修改配置文件,并启动server 第二步, 当前目录下面会生成一个 appendonly.aof文件,但是是空的 去客户端 开始操作后 ...

  5. 数据库分库分表(一)常见分布式主键ID生成策略

    主键生成策略 系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,下面介绍一些常见的ID生成策略. Sequence ID UUID GUID COMB Snowflake 最开始的自增ID为了实 ...

  6. 话说C语言的关键字volatile

    最近搞NVMe驱动需求分析,对volatile这个单词实在是再熟悉不过了. 而在C语言中,有一个关键字就叫做volatile, 其字面意思是"挥发性的, 不稳定的,可改变的". 那 ...

  7. [转]Hadoop集群_WordCount运行详解--MapReduce编程模型

    Hadoop集群_WordCount运行详解--MapReduce编程模型 下面这篇文章写得非常好,有利于初学mapreduce的入门 http://www.nosqldb.cn/1369099810 ...

  8. 数据库sqlite3在linux中的使用

    在linux下我们首先要获取root权限 当然也可是使用 sudo命令 接着让我们来安装sqlite3吧!博主当然是已经安装好了! 别急,的确你是安装好了sqlite3但是有一点必须要记住,你还没有安 ...

  9. Java大法之面向对象

    总觉得要写点东西,写写自己对知识的理解,对自己学的东西是否编程自己的了.我在想,如果让自己用自己的语言来解释,什么是面向对象,我可能会愣一下,我问自己什么是面向对象的时候,我想了想,自言自语说:面向对 ...

  10. Orchard源码:缓存设计

    概述 从缓存失效的几种方式开始了解Orchard缓存设计 1.设置失效时间 Func<int> retrieve = () => _cacheManager.Get("te ...