In dấu vết ngăn xếp của một ngoại lệ


81

Làm cách nào để in dấu vết ngăn xếp của một ngoại lệ đối với một luồng không phải là stderr? Một cách tôi đã tìm thấy là sử dụng getStackTrace () và in toàn bộ danh sách vào luồng.


Nếu bạn muốn lấy dấu vết ngoại lệ dưới dạng Chuỗi, bạn có thể gọi getStackTracephương thức Trowable (Ngoại lệ) sẽ trả về mảng các StackTraceElementđối tượng mà bạn có thể kết hợp thành một Chuỗi (sử dụng phương thức toString của đối tượng đó để lấy một dòng của dấu vết).
jcubic

Câu trả lời:


61

Throwable.printStackTrace(..)có thể lấy một PrintWriterhoặc PrintStreamđối số:

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

Điều đó nói rằng, hãy xem xét sử dụng giao diện ghi nhật ký như SLF4J với triển khai ghi nhật ký như LOGBack hoặc log4j .


77

Không đẹp, nhưng dù sao cũng là một giải pháp:

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

String stackTrace = writer.toString();

3
Đây là những gì tôi cần thiết (mặc dù tôi cảm thấy thực sự bẩn sử dụng nó!)
Henley Chiu

77

Có một dạng thay thế của Throwable.printStackTrace () lấy luồng in làm đối số. http://download.oracle.com/javase/6/docs/api/java/lang/Throwable.html#printStackTrace(java.io.PrintStream)

Ví dụ

catch(Exception e) {
    e.printStackTrace(System.out);
}

Thao tác này sẽ in dấu vết ngăn xếp thành std ra thay vì lỗi std.


4
@FranklinYu, toàn bộ điểm của câu hỏi là anh ấy không muốn in ra stderr, mà là một luồng tùy ý khác.
Mike Deck

9

Đối với những người theo chủ nghĩa tối giản dành cho nhà phát triển Android: Log.getStackTraceString(exception)


1
Bạn không thể sử dụng nó để in ra một luồng tùy ý. Nó chỉ hữu ích nếu bạn đã cấu hình trình ghi nhật ký.
rv

Tôi thích cách tiếp cận tối giản này, nhưng nó đã không hình thành rõ rệt với slf4j tôi :(
killjoy

7

Apache commons cung cấp tiện ích để chuyển đổi dấu vết ngăn xếp từ có thể ném thành chuỗi.

Sử dụng:

ExceptionUtils.getStackTrace(e)

Để có tài liệu đầy đủ, hãy tham khảo https://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html


Mặc dù câu trả lời này có vẻ rất đúng, nhưng nó không phải là câu trả lời cho câu hỏi. OP hỏi làm thế nào anh ta có thể in dấu vết ngăn xếp sang một luồng khác.
Buurman

Mặc dù điều này có thể không trả lời câu hỏi của OP, nhưng tôi nghĩ đây là cách tốt nhất để có một ngoại lệ dưới dạng Chuỗi, sử dụng một định dạng được thiết lập rất tốt. Cảm ơn!
Clint Eastwood

7

Tôi đã tạo một phương thức giúp lấy 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

Lớp Throwable cung cấp hai phương thức được đặt tên printStackTrace, một phương thức chấp nhận a PrintWritervà một phương thức nhận a PrintStream, xuất ra dấu vết ngăn xếp cho luồng đã cho. Hãy xem xét sử dụng một trong những thứ này.


1

Xem javadoc

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

0

Nếu bạn quan tâm đến một dấu vết ngăn xếp nhỏ gọn hơn với nhiều thông tin hơn (chi tiết gói) trông giống như:

  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]

bạn có thể thử sử dụng Throwables.writeTo từ lib spf4j .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.