打印异常的堆栈跟踪

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

217211 次浏览

Throwable.printStackTrace(..) can take a PrintWriter or PrintStream argument:

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

That said, consider using a logger interface like SLF4J with an logging implementation like LOGBack or log4j.

The Throwable class provides two methods named printStackTrace, one that accepts a PrintWriter and one that takes in a PrintStream, that outputs the stack trace to the given stream. Consider using one of these.

There is an alternate form of Throwable.printStackTrace() that takes a print stream as an argument. http://download.oracle.com/javase/6/docs/api/java/lang/Throwable.html#printStackTrace(java.io.PrintStream)

E.g.

catch(Exception e) {
e.printStackTrace(System.out);
}

This will print the stack trace to std out instead of std error.

Not beautiful, but a solution nonetheless:

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


String stackTrace = writer.toString();

See javadoc

out = some stream ...
try
{
}
catch ( Exception cause )
{
cause . printStrackTrace ( new PrintStream ( out ) ) ;
}

For the android dev minimalists: Log.getStackTraceString(exception)

I have created a method that helps with getting the 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();
}

Apache commons provides utility to convert the stack trace from throwable to string.

Usage:

ExceptionUtils.getStackTrace(e)

For complete documentation refer to https://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html

If you are interested in a more compact stack trace with more information (package detail) that looks like:

  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]

you can try to use Throwables.writeTo from the spf4j lib.