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.


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 .


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();

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.


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)


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


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

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.


1

Zobacz javadoc

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

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 .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.