Java 打印异常的堆栈跟踪

Java 打印异常的堆栈跟踪,java,exception,Java,Exception,如何将异常的堆栈跟踪打印到stderr以外的流?我发现的一种方法是使用getStackTrace()并将整个列表打印到流中。可丢弃。printStackTrace(…)可以使用PrintWriter或PrintStream参数: } catch (Exception ex) { ex.printStackTrace(new java.io.PrintStream(yourOutputStream)); } 这样说,考虑使用日志记录接口,像Oracle或.< /P>< P>日志记录实现。

如何将异常的堆栈跟踪打印到stderr以外的流?我发现的一种方法是使用getStackTrace()并将整个列表打印到流中。

可丢弃。printStackTrace(…)
可以使用
PrintWriter
PrintStream
参数:

} catch (Exception ex) {
    ex.printStackTrace(new java.io.PrintStream(yourOutputStream));
}

这样说,考虑使用日志记录接口,像Oracle或.< /P>< P>日志记录实现。该类提供了两种方法:“代码> PrtStActTrace,一个接受<代码> PrimTrrter ,一个接受<代码> PrrtStult<代码>,将堆栈跟踪输出到给定的流。考虑使用其中之一。

< P>有一个可替换的Primaby.PrrtStAccTrace()的形式,它将打印流作为参数。 例如


这将把堆栈跟踪打印到std out,而不是std error。

不美观,但仍然是一个解决方案:

StringWriter writer = new StringWriter();
PrintWriter printWriter = new PrintWriter( writer );
exception.printStackTrace( printWriter );
printWriter.flush();

String stackTrace = writer.toString();


对于android开发者极简主义者:
Log.getStackTraceString(异常)

我创建了一个有助于获取stackTrace的方法:

private static String getStackTrace(Exception ex) {
    StringBuffer sb = new StringBuffer(500);
    StackTraceElement[] st = ex.getStackTrace();
    sb.append(ex.getClass().getName() + ": " + ex.getMessage() + "\n");
    for (int i = 0; i < st.length; i++) {
      sb.append("\t at " + st[i].toString() + "\n");
    }
    return sb.toString();
}
私有静态字符串getStackTrace(异常示例){
StringBuffer sb=新的StringBuffer(500);
StackTraceElement[]st=ex.getStackTrace();
sb.append(例如getClass().getName()+“:”+ex.getMessage()+“\n”);
对于(int i=0;i
Apache commons提供了将堆栈跟踪从可丢弃转换为字符串的实用程序

用法:

ExceptionUtils.getStackTrace(e)
有关完整的文档,请参阅

如果您对更紧凑的堆栈跟踪和更多信息(包详细信息)感兴趣,它看起来像:

  java.net.SocketTimeoutException:Receive timed out
    at j.n.PlainDatagramSocketImpl.receive0(Native Method)[na:1.8.0_151]
    at j.n.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:143)[^]
    at j.n.DatagramSocket.receive(DatagramSocket.java:812)[^]
    at o.s.n.SntpClient.requestTime(SntpClient.java:213)[classes/]
    at o.s.n.SntpClient$1.call(^:145)[^]
    at ^.call(^:134)[^]
    at o.s.f.SyncRetryExecutor.call(SyncRetryExecutor.java:124)[^]
    at o.s.f.RetryPolicy.call(RetryPolicy.java:105)[^]
    at o.s.f.SyncRetryExecutor.call(SyncRetryExecutor.java:59)[^]
    at o.s.n.SntpClient.requestTimeHA(SntpClient.java:134)[^]
    at ^.requestTimeHA(^:122)[^]
    at o.s.n.SntpClientTest.test2h(SntpClientTest.java:89)[test-classes/]
    at s.r.NativeMethodAccessorImpl.invoke0(Native Method)[na:1.8.0_151]

您可以尝试从库中使用。

这就是我所需要的(尽管我使用它时感觉非常脏!)如果您想将异常跟踪作为字符串获取,您可以调用Trowable的
getStackTrace
方法(异常),该方法将返回可组合为一个字符串的
StackTraceeElement
对象数组(使用该对象的toString方法获取一行跟踪)。您不能使用该方法打印到任意流。只有在配置了记录器的情况下,该方法才有用。我喜欢这种最简单的方法,但它不能与我的slf4j结合使用:(@FranklinYu,问题的关键是他不想打印到stderr,而是打印到另一个任意流。虽然这个答案看起来非常正确,但它不是问题的答案。OP问他如何将堆栈跟踪打印到另一个流。尽管这可能无法回答OP的问题,但我认为这是最好的打印方式作为字符串的异常,使用非常好的格式。谢谢!
ExceptionUtils.getStackTrace(e)
  java.net.SocketTimeoutException:Receive timed out
    at j.n.PlainDatagramSocketImpl.receive0(Native Method)[na:1.8.0_151]
    at j.n.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:143)[^]
    at j.n.DatagramSocket.receive(DatagramSocket.java:812)[^]
    at o.s.n.SntpClient.requestTime(SntpClient.java:213)[classes/]
    at o.s.n.SntpClient$1.call(^:145)[^]
    at ^.call(^:134)[^]
    at o.s.f.SyncRetryExecutor.call(SyncRetryExecutor.java:124)[^]
    at o.s.f.RetryPolicy.call(RetryPolicy.java:105)[^]
    at o.s.f.SyncRetryExecutor.call(SyncRetryExecutor.java:59)[^]
    at o.s.n.SntpClient.requestTimeHA(SntpClient.java:134)[^]
    at ^.requestTimeHA(^:122)[^]
    at o.s.n.SntpClientTest.test2h(SntpClientTest.java:89)[test-classes/]
    at s.r.NativeMethodAccessorImpl.invoke0(Native Method)[na:1.8.0_151]