Роздрукуйте стек винятку


81

Як надрукувати стек винятку у потоці, відмінному від stderr? Один із способів, який я знайшов, - використовувати getStackTrace () і надрукувати весь список у потоці.


Якщо ви хочете отримати трасування винятку як String, ви можете викликати getStackTraceметод Trowable (виняток), який поверне масив StackTraceElementоб'єктів, які ви можете об'єднати в один рядок (за допомогою методу toString цього об'єкта, щоб отримати один рядок трасування).
jcubic

Відповіді:


62

Throwable.printStackTrace(..)може взяти аргумент PrintWriterабо PrintStream:

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

Тим не менш, розгляньте можливість використання інтерфейсу реєстратора, такого як SLF4J, з реалізацією журналювання, такою як LOGBack або log4j .


77

Не красиво, але рішення тим не менше:

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

String stackTrace = writer.toString();

3
Це те, що мені потрібно (хоча я відчуваю себе дуже брудно, використовуючи це!)
Хенлі Чіу

77

Існує альтернативна форма 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.


4
@FranklinYu, вся суть питання в тому, що він хоче не друкувати на stderr, а на інший довільний потік.
Mike Deck

9

Для мінімалістів розробників Android: Log.getStackTraceString(exception)


1
Ви не можете використовувати це для друку у довільному потоці. Це корисно, лише якщо ви налаштували реєстратор.
rv

Мені сподобався цей мінімалістичний підхід, але він не здивувався моїм slf4j :(
killjoy

7

Apache commons надає утиліту для перетворення трасування стека з метаданого в рядок.

Використання:

ExceptionUtils.getStackTrace(e)

Повну документацію див. На https://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html


Хоча ця відповідь виглядає дуже правильною, вона не є відповіддю на питання. OP запитав, як він може надрукувати трасування стека в інший потік.
Буурман,

Незважаючи на те, що це може не відповісти на запитання OP, я думаю, що це найкращий спосіб мати виняток як String, використовуючи дуже усталений формат. Дякую!
Клінт Іствуд,

7

Я створив метод, який допомагає отримати 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 надає два іменовані методи printStackTrace, один з яких приймає a PrintWriterта той, що приймає a PrintStream, який виводить трасування стека до заданого потоку. Подумайте про використання одного з них.


1

Дивіться javadoc

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

0

Якщо ви зацікавлені в більш компактному трасуванні стека з додатковою інформацією (деталями пакета), яка виглядає так:

  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 .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.