Як надрукувати стек винятку у потоці, відмінному від stderr? Один із способів, який я знайшов, - використовувати getStackTrace () і надрукувати весь список у потоці.
Відповіді:
Throwable.printStackTrace(..)може взяти аргумент PrintWriterабо PrintStream:
} catch (Exception ex) {
ex.printStackTrace(new java.io.PrintStream(yourOutputStream));
}
Тим не менш, розгляньте можливість використання інтерфейсу реєстратора, такого як SLF4J, з реалізацією журналювання, такою як LOGBack або log4j .
Не красиво, але рішення тим не менше:
StringWriter writer = new StringWriter();
PrintWriter printWriter = new PrintWriter( writer );
exception.printStackTrace( printWriter );
printWriter.flush();
String stackTrace = writer.toString();
Існує альтернативна форма Throwable.printStackTrace (), яка приймає потік друку як аргумент. http://download.oracle.com/javase/6/docs/api/java/lang/Throwable.html#printStackTrace(java.io.PrintStream)
Напр
catch(Exception e) {
e.printStackTrace(System.out);
}
Це надрукує трасування стека на std замість помилки std.
Apache commons надає утиліту для перетворення трасування стека з метаданого в рядок.
Використання:
ExceptionUtils.getStackTrace(e)
Повну документацію див. На https://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html
Я створив метод, який допомагає отримати 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 надає два іменовані методи printStackTrace, один з яких приймає a PrintWriterта той, що приймає a PrintStream, який виводить трасування стека до заданого потоку. Подумайте про використання одного з них.
Якщо ви зацікавлені в більш компактному трасуванні стека з додатковою інформацією (деталями пакета), яка виглядає так:
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]
Ви можете спробувати використовувати Throwables.writeTo з бібліотеки spf4j .
getStackTraceметод Trowable (виняток), який поверне масивStackTraceElementоб'єктів, які ви можете об'єднати в один рядок (за допомогою методу toString цього об'єкта, щоб отримати один рядок трасування).