一、前言

  直接用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. IDEA 笔记汇总

    Intellij IDEA 像eclipse那样给maven添加依赖 Intellij idea maven 引用无法搜索远程仓库的解决方案 Intellij IDEA 封装Jar包(提示错误: 找不 ...

  2. shell-012:批量创建用户

    # #!/bin/bash # 批量创建用户 # 分析:用命令给用户创建密码的方法有两种 # . 可以直接用echo的方法 # echo "abc-123" |passwd roo ...

  3. 安装vuecli和使用elememtUi

    首先需要下载node.js,这里只需要一步步的安装就可以,无需要做其他的事, 第二步:安装vue 第三步:安装脚手架 第四步: 由于国内访问npm比较慢,可以按照cnpm npm install -g ...

  4. ubuntu 14.04网卡配置以及关闭防火墙

    一.Ubuntu网卡配置如下: 在文件/etc/network/interfaces中进行以下配置 auto lo iface lo inet lookback auto eth0 iface eth ...

  5. windows 虚拟机VMware 安装linux系统注意事项!!!

    1.主机CPU是否支持虚拟化技术?      启动 CPUZ 软件(如下图) 注: 32位系统查看使用CPUZ_x86软件             64位系统查看使用CPUZ_x64软件    启动后 ...

  6. Mac下使Iterm2开机启动不显示界面

    一.在登录项上添加Iterm2的启动项 二.打开Iterm2 1.启动后会显示Iterm2,此时点击关闭按钮,保证桌面上没有任何的控制台窗口. 2.按[Command]+[Shift]+[S],保存名 ...

  7. apk反编译——基础是内功,得牢,飞跃还得多看源码,不同思想的碰撞才能产生火花,加油!!!!!!!!

    1.获取java源代码 1.1 dex2jar&jd-gui dex2jar:将apk反编译成class文件(classes.dex转化成jar文件) jd-gui:查看APK中classes ...

  8. 数据库~Mysql派生表注意的几点~关于百万数据的慢查询问题

    基础概念 派生表是从SELECT语句返回的虚拟表.派生表类似于临时表,但是在SELECT语句中使用派生表比临时表简单得多,因为它不需要创建临时表的步骤. 术语:*派生表*和子查询通常可互换使用.当SE ...

  9. java突破------一撸到底(做Java开发,遇到瓶颈是保持现状还是寻求突破?)

    java突破------一撸到底(做Java开发,遇到瓶颈是保持现状还是寻求突破?) 很多人做Java开发2.3年之后,都会觉得自己遇到了瓶颈.什么都会又什么都不会,如何改变困境,为什么很多人写了7. ...

  10. log4php0.9的详细配备实例说明

    一.什么是log4php: log4j在JAVA中可算是大名鼎鼎的日志开发包了,它为apche组织维护项目,VxR兄使用php来实现了log4j的功能, 目前log4php已经作为log4j的一个子项 ...