Wydrukuj ślad stosu wyjątku

81

Jak wydrukować ślad stosu wyjątku do strumienia innego niż stderr? Jednym ze sposobów, które znalazłem, jest użycie metody getStackTrace () i wydrukowanie całej listy do strumienia.

rv
źródło
Jeśli chcesz uzyskać ślad wyjątku jako String, możesz wywołać getStackTracemetodę Trowable (Exception), która zwróci tablicę StackTraceElementobiektów, które możesz połączyć w jeden String (używając metody toString tego obiektu, aby uzyskać jedną linię śledzenia).
jcubic

Odpowiedzi:

62

Throwable.printStackTrace(..)może przyjąć argument PrintWriterlub PrintStream:

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

To powiedziawszy, rozważ użycie interfejsu rejestratora, takiego jak SLF4J z implementacją rejestrowania, taką jak LOGBack lub log4j .

Bozho
źródło
77

Nie jest to piękne, ale rozwiązanie:

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

String stackTrace = writer.toString();
Maurício Linhares
źródło
3
To jest to, czego potrzebowałem (chociaż czuję się naprawdę brudny, używając go!)
Henley Chiu
77

Istnieje alternatywna forma Throwable.printStackTrace (), która przyjmuje strumień wydruku jako argument. http://download.oracle.com/javase/6/docs/api/java/lang/Throwable.html#printStackTrace(java.io.PrintStream)

Na przykład

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

Spowoduje to wydrukowanie śladu stosu na wyjście standardowe zamiast błędu standardowego.

Mike Deck
źródło
4
@FranklinYu, cały problem polega na tym, że nie chce on drukować na stderr, ale do innego dowolnego strumienia.
Mike Deck
9

Dla minimalistów programistów Androida: Log.getStackTraceString(exception)

PatrickMA
źródło
1
Nie możesz tego użyć do drukowania w dowolnym strumieniu. Jest to przydatne tylko wtedy, gdy masz skonfigurowany rejestrator.
rv
Podobało mi się to minimalistyczne podejście, ale nie zdziała się z moim slf4j :(
killjoy
7

Apache commons zapewnia narzędzie do konwersji śladu stosu z elementu do rzucania na ciąg.

Stosowanie:

ExceptionUtils.getStackTrace(e)

Pełną dokumentację można znaleźć pod adresem https://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html

Rathan
źródło
Chociaż ta odpowiedź wygląda na bardzo poprawną, nie jest odpowiedzią na pytanie. OP zapytał, jak może wydrukować ślad stosu do innego strumienia.
Buurman
Mimo że może to nie odpowiadać na pytanie OP, myślę, że jest to najlepszy sposób na utworzenie wyjątku jako ciągu, przy użyciu bardzo dobrze ugruntowanego formatu. Dzięki!
Clint Eastwood
7

Stworzyłem metodę, która pomaga w uzyskaniu 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();
}
kuppurangi
źródło
3

Throwable klasa zawiera dwie metody nazwie printStackTracetaki, który przyjmuje PrintWriteri który przyjmuje w sposób PrintStream, który wyprowadza ślad stosu do danego strumienia. Rozważ użycie jednego z nich.

templatetypedef
źródło
1

Zobacz javadoc

out = some stream ...
try
{
}
catch ( Exception cause )
{
      cause . printStrackTrace ( new PrintStream ( out ) ) ;
}
emory
źródło
0

Jeśli jesteś zainteresowany bardziej zwartym śledzeniem stosu z dodatkowymi informacjami (szczegółami pakietu), które wyglądają następująco:

  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]

możesz spróbować użyć Throwables.writeTo z biblioteki spf4j .

user2179737
źródło