java 打印完整的堆栈信息

前言

在实际的项目中,免不了遇到各种各样的异常,通常我们会有日志系统对错误信息以及堆栈信息进行收集,例如 graylog、flume+kafka+storm 、elk 等。
但是在遇到异常时,我们也需要将异常情况以邮件或者微信或者短信等方式通知我们,由于微信和短信对文本的长度有限制,所以我们会将具体的堆栈信息打印出来通过邮件通知我们。

  1. 使用 io 流将堆栈信息打印出来
 public static String getStackTrace(Exception e) {
        StringWriter sw = null;
        PrintWriter pw = null;
        try {
            sw = new StringWriter();
            pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();

        } catch (Exception e2) {
            e2.printStackTrace();
        } finally {
            if (sw != null) {
                try {
                    sw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (pw != null) {
                pw.close();
            }
        }
        return sw.toString();
    }
  1. 使用 common-lang3 提供的工具类

在 common-lang3 包中提供了 ExceptionUtils 类来帮助读取堆栈信息

pom 依赖:

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
	<version>3.5</version>
</dependency>
public static String getStackTraceV2(Exception e) {
    return org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
}

看一下源码咋实现的:

//-----------------------------------------------------------------------
 /**
  * <p>Gets the stack trace from a Throwable as a String.</p>
  *
  * <p>The result of this method vary by JDK version as this method
  * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
  * On JDK1.3 and earlier, the cause exception will not be shown
  * unless the specified throwable alters printStackTrace.</p>
  *
  * @param throwable  the <code>Throwable</code> to be examined
  * @return the stack trace as generated by the exception's
  *  <code>printStackTrace(PrintWriter)</code> method
  */
 public static String getStackTrace(final Throwable throwable) {
     final StringWriter sw = new StringWriter();
     final PrintWriter pw = new PrintWriter(sw, true);
     throwable.printStackTrace(pw);
     return sw.getBuffer().toString();
 }

和第一种方法一样,所以很多东西,别人已经造好轮子了,我们可以直接使用,但是我们也要明白其实现原理。

猜你喜欢

转载自blog.csdn.net/wjavadog/article/details/93778802