Drucken Sie die Stapelverfolgung einer Ausnahme

81

Wie drucke ich den Stack-Trace einer Ausnahme in einen anderen Stream als stderr? Eine Möglichkeit, die ich gefunden habe, besteht darin, getStackTrace () zu verwenden und die gesamte Liste in den Stream zu drucken.

rv
quelle
Wenn Sie eine Ausnahmeverfolgung als getStackTraceZeichenfolge abrufen möchten, können Sie die Methode Trowable (die Ausnahme) aufrufen, die ein Array von StackTraceElementObjekten zurückgibt , die Sie zu einer Zeichenfolge kombinieren können (mithilfe der toString-Methode dieses Objekts, um eine Zeile einer Ablaufverfolgung abzurufen).
jcubic

Antworten:

61

Throwable.printStackTrace(..)kann ein PrintWriteroder PrintStreamArgument nehmen:

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

Erwägen Sie jedoch die Verwendung einer Logger-Schnittstelle wie SLF4J mit einer Protokollierungsimplementierung wie LOGBack oder log4j .

Bozho
quelle
77

Nicht schön, aber dennoch eine Lösung:

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

String stackTrace = writer.toString();
Maurício Linhares
quelle
3
Dies ist, was ich brauchte (obwohl ich mich wirklich schmutzig fühle, wenn ich es benutze!)
Henley Chiu
77

Es gibt eine alternative Form von Throwable.printStackTrace (), die einen Druckstrom als Argument verwendet. http://download.oracle.com/javase/6/docs/api/java/lang/Throwable.html#printStackTrace(java.io.PrintStream)

Z.B

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

Dadurch wird die Stapelverfolgung anstelle des Standardfehlers als Standard ausgegeben.

Mike Deck
quelle
4
@FranklinYu, der springende Punkt der Frage ist, dass er nicht auf stderr drucken möchte, sondern auf einen anderen beliebigen Stream.
Mike Deck
9

Für die Android Dev Minimalisten: Log.getStackTraceString(exception)

PatrickMA
quelle
1
Sie können dies nicht zum Drucken in einem beliebigen Stream verwenden. Dies ist nur nützlich, wenn Sie einen Logger konfiguriert haben.
rv
Ich mochte diesen minimalistischen Ansatz, aber er passte nicht zu meinem slf4j :(
killjoy
7

Apache Commons bietet ein Dienstprogramm zum Konvertieren des Stack-Trace von Throwable in String.

Verwendung:

ExceptionUtils.getStackTrace(e)

Eine vollständige Dokumentation finden Sie unter https://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html

Rathan
quelle
Diese Antwort sieht zwar sehr richtig aus, ist aber keine Antwort auf die Frage. OP fragte, wie er den Stack-Trace in einen anderen Stream drucken könne.
Buurman
Auch wenn dies die Frage von OP möglicherweise nicht beantwortet, denke ich, dass dies der beste Weg ist, eine Ausnahme als String in einem sehr gut etablierten Format zu haben. Vielen Dank!
Clint Eastwood
7

Ich habe eine Methode erstellt, die beim Abrufen von stackTrace hilft:

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();
}
kuppurangi
quelle
3

Die Throwable- Klasse bietet zwei benannte Methoden printStackTrace, eine, die a akzeptiert, PrintWriterund eine, die a akzeptiert, und PrintStreamdie den Stack-Trace an den angegebenen Stream ausgibt. Erwägen Sie die Verwendung einer dieser Optionen.

templatetypedef
quelle
1

Siehe Javadoc

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

Wenn Sie an einer kompakteren Stapelverfolgung mit weiteren Informationen (Paketdetails) interessiert sind, die wie folgt aussieht:

  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]

Sie können versuchen, Throwables.writeTo aus der spf4j-Bibliothek zu verwenden .

user2179737
quelle