zoukankan      html  css  js  c++  java
  • 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():在控制台打印出异常堆栈(异常类型、错误信息描述和出错位置等)。
  • 相关阅读:
    flask——flask-sqlachemy中的一对多,多对多关系
    flask——flask-sqlachemy的使用,模块划分
    Ubuntu下安装JDK和Open Jdk
    flask——全文检索
    Flask——部署
    在Ubuntu上安装Chrome浏览器和ChromeDriver
    jinja2模板语言的循环序号
    CentOS7安装mongodb
    CentOS7安装PhantomJS
    使用screen在后台运行程序
  • 原文地址:https://www.cnblogs.com/gavincoder/p/10092187.html
Copyright © 2011-2022 走看看