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.