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.
Odpowiedzi:
Throwable.printStackTrace(..)
może przyjąć argument PrintWriter
lub 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 .
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();
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.
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
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();
}
Throwable klasa zawiera dwie metody nazwie printStackTrace
taki, który przyjmuje PrintWriter
i który przyjmuje w sposób PrintStream
, który wyprowadza ślad stosu do danego strumienia. Rozważ użycie jednego z nich.
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 .
getStackTrace
metodę Trowable (Exception), która zwróci tablicęStackTraceElement
obiektów, które możesz połączyć w jeden String (używając metody toString tego obiektu, aby uzyskać jedną linię śledzenia).