Làm thế nào tôi có thể chuyển đổi một dấu vết ngăn xếp thành một chuỗi?


1502

Cách dễ nhất để chuyển đổi kết quả của Throwable.getStackTrace()một chuỗi mô tả stacktrace là gì?


6
Bởi vì câu trả lời của jqno thực sự sử dụng phương thức throwable.getStackTrace () mà bạn đã chỉ định trong câu hỏi của mình, trong khi Brian thì không. Anh ta sử dụng throwable.printStackTrace () để thay thế.
Stijn de Witt

10
Gần như mọi dự án Java nên bao gồm Apache commons-lang. Nó bao gồm nhiều phương pháp tiện lợi thực hiện các nhu cầu phát triển cực kỳ phổ biến.
Russell Silva

20
@StijndeWitt Ba dòng mã đó gần như chắc chắn cần bao thanh toán ra khỏi nơi bạn đã gọi chúng. Vì bạn không biết đặt chúng ở đâu, chúng sẽ đi vào hộp công cụ tiện ích của bạn với tất cả các đoạn hữu ích khác. Chơi lô tô! bạn vừa mới phát minh ra ổi / commons-lang / bất cứ điều gì ... chỉ là không tốt lắm. Thay vào đó, hãy nhập thư viện tiện ích hợp lý và lưu lại phát minh lại bánh xe. Dấu hiệu thực sự của một người mới là nghĩ rằng bạn có thể làm một công việc tốt hơn so với các nhà văn thư viện.
Andrew Spencer

6
1. Guava có - throwables.getStackTraceAsString (e) 2. Apache Commons Lang - ExceptionUtils.getFullStackTrace 3. Viết phương thức tùy chỉnh của riêng chúng tôi
2323036

8
@AndrewSpencer Tôi không hiểu tại sao các bạn cố gắng hết sức để bash StijndeWitt vì muốn đạt được điều này với một số đoạn nhỏ. Thực sự không có nhiều nguy hiểm khi viết một phương thức tiện ích nhỏ bé (tôi không thấy nó là "SHEER ARROGANCE oh nooooo !! anh ấy nghĩ rằng anh ấy tốt hơn Apache !!"). Có rất nhiều dự án, đặc biệt là các ngôn ngữ JVM không phải Java mà thực sự không muốn bao gồm Guava hoặc Commons Lang chỉ để ghi nhật ký stacktrace. Tôi viết các thư viện Scala & Clojure và chắc chắn sẽ không biến Apache Commons Lang thành một phụ thuộc bắc cầu chỉ cho một phương thức.
jm0

Câu trả lời:


1039

Người ta có thể sử dụng phương pháp sau để chuyển đổi Exceptiondấu vết ngăn xếp thành String. Lớp này có sẵn trong Apache commons-lang, thư viện phụ thuộc phổ biến nhất với nhiều nguồn mở phổ biến

org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)


88
@Stijn - công bằng mà nói (tôi đã viết câu trả lời được bình chọn cao nhất hiện nay bên dưới) thật đáng để xem commons-lang để biết thêm nhiều chức năng
Brian Agnew

54
@StijndeWitt Commons Lang khá phổ biến. Nó đã có mặt trong hầu hết các dự án / proyects của tôi tại nơi làm việc.
WhyNotHugo

16
@Hugo cảm ơn, tôi sẽ sử dụng StringWriter để tránh thêm thư viện mới - hóa ra nó đã phụ thuộc vào 3 phụ thuộc của tôi. Vì vậy, với phần còn lại, kiểm tra nếu bạn đã có nó.
Nathanial

33
@MartinAsenov - theo logic của bạn, bạn sẽ không bao giờ sử dụng một thư viện như vậy, phải không? Bạn sẽ không sử dụng nó trừ khi bạn đã sử dụng nó?
Brian Agnew

16
Fyi, gói đã thay đổi và lớp hiện tại : org.apache.commons.lang3.exception.ExceptionUtils.
schmmd

2201

Sử dụng Throwable.printStackTrace(PrintWriter pw)để gửi theo dõi ngăn xếp cho một nhà văn thích hợp.

import java.io.StringWriter;
import java.io.PrintWriter;

// ...

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); // stack trace as a string
System.out.println(sStackTrace);

505
Nếu bạn không thích bao gồm một thư viện bên ngoài cho một cái gì đó nhỏ và đơn giản như thế này, hãy sử dụng câu trả lời này.
Stijn de Witt

8
Điều này không cắt theo dõi ngăn xếp, giống như cách printStackTrace (). Tất cả các ngoại lệ trong ngăn xếp đều có thể nhìn thấy nhưng đối với mỗi ngoại lệ, ngăn xếp có thể được cắt bớt. Bất cứ ai yêu cầu toàn bộ dấu vết nên xem xét điều này.
Laila Agaev

5
Điều này, như hóa ra, gần như chính xác là phương thức ExceptionUtils.getStackTrace () của apache làm gì. Hầu như để thư thực sự.
ticktock

6
@BrianAgnew, bạn có nên đóng StringWriterPrintWriterkhông?
Muhammad Gelbana

13
@BrianAgnew, cảm ơn bạn đã trả lời. Nó khiến tôi tò mò và đây là những gì tôi tìm thấy: stackoverflow.com/questions/14542535/
Khăn

459

Điều này sẽ làm việc:

StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();

69
Súc tích trong bối cảnh java luôn luôn đồi trụy. Điều đó printStackTracechỉ nên trả về chuỗi, để lại quyết định về việc in hay không cho người dùng :)
dmitry

35
printStackTrace in trong bảng điều khiển có thể chấp nhận được, nhưng ít nhất một getStackTrace trả lại nó dưới dạng Chuỗi nên có sẵn theo mặc định
Mateus Viccari

5
Phần nào của điều này là súc tích? Bạn phải xây dựng 2 đối tượng tồn tại không có mục đích nào khác ngoài việc đặt dấu vết ngăn xếp thành một chuỗi.
ArtOfWarfare

7
@dmitry Một phương thức được gọi printXXX()nên in XXX.
Hầu tước Lorne

2
@Greg Thật ra điều đó thậm chí không mỉa mai, nó chỉ cần đọc đơn giản những gì anh ấy nói.
Andrew

224

Nếu bạn đang phát triển cho Android, một cách dễ dàng hơn nhiều là sử dụng điều này:

import android.util.Log;

String stackTrace = Log.getStackTraceString(exception); 

Định dạng giống như getStacktrace, ví dụ:

09-24 16:09:07.042: I/System.out(4844): java.lang.NullPointerException
09-24 16:09:07.042: I/System.out(4844):   at com.temp.ttscancel.MainActivity.onCreate(MainActivity.java:43)
09-24 16:09:07.042: I/System.out(4844):   at android.app.Activity.performCreate(Activity.java:5248)
09-24 16:09:07.043: I/System.out(4844):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.access$800(ActivityThread.java:139)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
09-24 16:09:07.043: I/System.out(4844):   at android.os.Handler.dispatchMessage(Handler.java:102)
09-24 16:09:07.043: I/System.out(4844):   at android.os.Looper.loop(Looper.java:136)
09-24 16:09:07.044: I/System.out(4844):   at android.app.ActivityThread.main(ActivityThread.java:5097)
09-24 16:09:07.044: I/System.out(4844):   at java.lang.reflect.Method.invokeNative(Native Method)
09-24 16:09:07.044: I/System.out(4844):   at java.lang.reflect.Method.invoke(Method.java:515)
09-24 16:09:07.044: I/System.out(4844):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
09-24 16:09:07.044: I/System.out(4844):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)

2
Cảm ơn. Trong trường hợp này, ngày và thẻ không được ghi trong mỗi hàng như trong printStackTrace ().
CoolMind

1
Trên thực tế, Log.getStackTraceString trong lõi của nó sử dụng StringWriter và Printwriter đã đề cập ở trên.
MikeL

2
Cách dễ nhất để chỉ IN nó trong nhật ký Android là: Log.e("TAG", "My message", new Throwable());
Erick M. Sprengel


113

CẢNH BÁO: Không bao gồm nguyên nhân (thường là bit hữu ích!)

public String stackTraceToString(Throwable e) {
    StringBuilder sb = new StringBuilder();
    for (StackTraceElement element : e.getStackTrace()) {
        sb.append(element.toString());
        sb.append("\n");
    }
    return sb.toString();
}

1
Tôi sẽ sử dụng phần mở rộng của phương pháp này nếu bạn muốn cắt theo dõi, ví dụ: truyền tham số maxLines và chỉ thêm nhiều dòng đó vào dấu vết
Người bán giàu

Các dấu ngoặc đơn sau e.getStackTrace bị thiếu. chuỗi tĩnh công khai stackTraceToString (Ngoại lệ e) {StringBuilder sb = new StringBuilder (); cho (phần tử StackTraceE bổ sung: e.getStackTrace ()) {sb.append (Element.toString ()); sb.append ("<br />"); } return sb.toString (); }
rlc

2
Không chắc chắn, nhưng tôi nghĩ rằng điều này sẽ không in dấu vết ngăn xếp của ngoại lệ nguyên nhân gốc.
apoorv020

7
Dù bạn làm gì, đừng cắt dấu vết. Điều đó đã xảy ra với tôi rất nhiều lần khi tôi nhìn vào dấu vết ngăn xếp trong nhật ký GlassFish có các phần hữu ích được cắt bỏ.
cayhorstmann

Sử dụng String.format("%n")hoặc một cái gì đó tương tự thay vì "\n"làm cho DOS than phiền.
ceving

89

Đối với tôi cách sạch nhất và dễ nhất là:

import java.util.Arrays;
Arrays.toString(e.getStackTrace());

37
Mã sạch, nhưng đầu ra thì không. Cuối cùng, bạn phải thực hiện một .replaceAll (",", "\ n"). Tuy nhiên, bạn mất đi sự thụt lề mà printStackTrace đề xuất.
giận dữ

4
Điều này hữu ích khi bạn đăng nhập theo dõi trong một dòng duy nhất
webj Racer

28
public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}

1
Xin chào, tôi chỉ muốn chỉ ra rằng phần bình luận của câu trả lời được trích dẫn chỉ ra rằng StringWriterPrintWritercác đối tượng phải là closed .... (hoặc tôi đoán chỉ những PrintWriternhu cầu được đóng lại vì đóng nó cũng nên đóng lại StringWriter)
Eric

8
Lấy cảm hứng từ bạn có nghĩa là sao chép? Bạn chỉ đặt nó trong một phương pháp ... Đọc các câu trả lời ở đây giống như xem "Ngày
con rắn

26

Đoạn mã sau cho phép bạn lấy toàn bộ stackTrace với Stringđịnh dạng mà không cần sử dụng các API như log4J hoặc thậm chí java.util.Logger:

catch (Exception e) {
    StackTraceElement[] stack = e.getStackTrace();
    String exception = "";
    for (StackTraceElement s : stack) {
        exception = exception + s.toString() + "\n\t\t";
    }
    System.out.println(exception);
    // then you can send the exception string to a external file.
}

1
ya nhưng nó hơi cồng kềnh bạn không nghĩ sao? trong bất kỳ khuôn khổ ghi nhật ký dự án có kích thước hợp lý là điều bắt buộc, tại sao phải bận tâm
mzzzzb

Điều này là không đưa ra thông báo lỗi trong đầu. có thể được thêm vào mặc dù
kommradHomer

Bạn có thể muốn sử dụng StringBuffer thay vì ghép nối đơn giản.
depda1994

Điều này hữu ích khi bạn không được phép đăng nhập tin nhắn vì lý do riêng tư.
A1m

Mặc dù vậy, hãy lưu ý rằng giải pháp này sẽ không ghi lại các nguyên nhân bên trong
A1m

19

Đây là một phiên bản có thể sao chép trực tiếp vào mã:

import java.io.StringWriter; 
import java.io.PrintWriter;

//Two lines of code to get the exception into a StringWriter
StringWriter sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));

//And to actually print it
logger.info("Current stack trace is:\n" + sw.toString());

Hoặc, trong một khối bắt

} catch (Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    logger.info("Current stack trace is:\n" + sw.toString());
}

điều này sẽ tiếp tục vượt quá phạm vi của chức năng hiện tại tức là. nơi Throwableđược định nghĩa, phải không?
n611x007

16
Arrays.toString(thrown.getStackTrace())

Là cách dễ nhất để chuyển đổi kết quả thành Chuỗi Tôi đang sử dụng điều này trong chương trình của mình để in theo dõi ngăn xếp

LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});

Làm việc cho tôi, không có gì có vẻ được cắt! Đơn giản hơn câu trả lời khác quá với bất kỳ thư viện bên ngoài, câu trả lời tuyệt vời!
Shaung Cheng

16

In dấu vết ngăn xếp thành a PrintStream, sau đó chuyển đổi nó thành String:

// ...

catch (Exception e)
{
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    e.printStackTrace(new PrintStream(out));
    String str = new String(out.toByteArray());

    System.out.println(str);
}

1
đây là câu trả lời trực tiếp nhất
DaSqy Stc

11

In dấu vết ngăn xếp thành chuỗi

import java.io.PrintWriter;
import java.io.StringWriter;

public class StackTraceUtils {
    public static String stackTraceToString(StackTraceElement[] stackTrace) {
        StringWriter sw = new StringWriter();
        printStackTrace(stackTrace, new PrintWriter(sw));
        return sw.toString();
    }
    public static void printStackTrace(StackTraceElement[] stackTrace, PrintWriter pw) {
        for(StackTraceElement stackTraceEl : stackTrace) {
            pw.println(stackTraceEl);
        }
    }
}

Nó hữu ích khi bạn muốn in theo dõi ngăn xếp luồng hiện tại mà không cần tạo ra Throwable- nhưng lưu ý rằng việc tạo mới Throwablevà theo dõi ngăn xếp từ đó thực sự nhanh hơn và rẻ hơn so với gọi Thread.getStackTrace.


11

Kotlin

Mở rộng lớp throwable sẽ cung cấp cho bạn thuộc tính String error.stackTraceString:

val Throwable.stackTraceString: String
  get() {
    val sw = StringWriter()
    val pw = PrintWriter(sw)
    this.printStackTrace(pw)
    return sw.toString()
  }

10
private String getCurrentStackTraceString() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    return Arrays.stream(stackTrace).map(StackTraceElement::toString)
            .collect(Collectors.joining("\n"));
}

1
Cảm ơn bạn eddyrkokr! Nó hoạt động hoàn hảo cho tất cả các đầu mối của tôi. Tôi vừa mới thêm nó vào lớp TestNG cơ sở và nó thu thập từng stacktraces từ tất cả các bài kiểm tra của tôi!
Krzysztof Walczewski

9

Việc bắn tỉa thông minh trong các bình luận đầu tiên rất thú vị, nhưng nó thực sự phụ thuộc vào những gì bạn đang cố gắng làm. Nếu bạn chưa có thư viện chính xác, thì 3 dòng mã (như trong câu trả lời của D. Classicalblewski) là hoàn hảo. OTOH, nếu bạn đã có thư viện apache.commons (vì hầu hết các dự án lớn sẽ có), thì câu trả lời của Amar ngắn hơn. OK, bạn có thể mất mười phút để lấy thư viện và cài đặt chính xác (ít hơn một nếu bạn biết bạn đang làm gì). Nhưng đồng hồ đang kêu, vì vậy bạn có thể không có thời gian rảnh rỗi. Jarek Przygódzki đã có một cảnh báo thú vị - "Nếu bạn không cần ngoại lệ lồng nhau".

Nhưng nếu tôi làm cần ngăn xếp dấu vết đầy đủ, lồng nhau và tất cả? Trong trường hợp đó, bí mật là sử dụng getFullStackTrace của apache.common (xem http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html # getFullStackTrace% 28java.lang. Có thể chia sẻ% 29 )

Nó đã cứu thịt xông khói của tôi. Cảm ơn, Amar, cho gợi ý!


9

Mã từ Apache Commons Lang 3.4 ( JavaDoc ):

public static String getStackTrace(final Throwable throwable) {
    final StringWriter sw = new StringWriter();
    final PrintWriter pw = new PrintWriter(sw, true);
    throwable.printStackTrace(pw);
    return sw.getBuffer().toString();
}

Sự khác biệt với các câu trả lời khác là nó sử dụng autoFlush trên PrintWriter.


8

Nếu không có java.io.*nó có thể được thực hiện như thế này.

String trace = e.toString() + "\n";                     

for (StackTraceElement e1 : e.getStackTrace()) {
    trace += "\t at " + e1.toString() + "\n";
}   

Và sau đó trace biến giữ dấu vết ngăn xếp của bạn. Đầu ra cũng giữ nguyên nhân ban đầu, đầu ra giống hệt vớiprintStackTrace()

Ví dụ, printStackTrace()sản lượng:

java.io.FileNotFoundException: / (Is a directory)
    at java.io.FileOutputStream.open0(Native Method)
    at java.io.FileOutputStream.open(FileOutputStream.java:270)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
    at Test.main(Test.java:9)

Các tracechuỗi nắm giữ, khi in đểstdout

java.io.FileNotFoundException: / (Is a directory)
     at java.io.FileOutputStream.open0(Native Method)
     at java.io.FileOutputStream.open(FileOutputStream.java:270)
     at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
     at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
     at Test.main(Test.java:9)

5

Phiên bản Scala

def stackTraceToString(e: Exception): String = {
  import java.io.PrintWriter
  val sw = new StringWriter()
  e.printStackTrace(new PrintWriter(sw))
  sw.toString
}

5

nếu bạn đang sử dụng Java 8, hãy thử điều này

Arrays.stream(e.getStackTrace())
                .map(s->s.toString())
                .collect(Collectors.joining("\n"));

bạn có thể tìm mã cho getStackTrace()hàm được cung cấp bởi Throwable.java:

public StackTraceElement[] getStackTrace() {
    return getOurStackTrace().clone();
}

và cho StackTraceElement, nó cung cấp toString()như:

public String toString() {
    return getClassName() + "." + methodName +
        (isNativeMethod() ? "(Native Method)" :
         (fileName != null && lineNumber >= 0 ?
          "(" + fileName + ":" + lineNumber + ")" :
          (fileName != null ?  "("+fileName+")" : "(Unknown Source)")));
}

Vì vậy, chỉ cần tham gia StackTraceElementvới "\ n".


Giải pháp này không tôn trọng tab dấu vết ngăn xếp nếu không nó hoạt động rất tốt!
krizajb

4

một ngoại lệ về câu trả lời của Gala cũng sẽ bao gồm các nguyên nhân cho ngoại lệ:

private String extrapolateStackTrace(Exception ex) {
    Throwable e = ex;
    String trace = e.toString() + "\n";
    for (StackTraceElement e1 : e.getStackTrace()) {
        trace += "\t at " + e1.toString() + "\n";
    }
    while (e.getCause() != null) {
        e = e.getCause();
        trace += "Cause by: " + e.toString() + "\n";
        for (StackTraceElement e1 : e.getStackTrace()) {
            trace += "\t at " + e1.toString() + "\n";
        }
    }
    return trace;
}

4

Giải pháp là chuyển đổi stackTrace của mảng thành kiểu dữ liệu chuỗi . Xem ví dụ sau:

import java.util.Arrays;

try{

}catch(Exception ex){
    String stack = Arrays.toString(ex.getStackTrace());
    System.out.println("stack "+ stack);
}

4

Với API Java Stream 8, bạn có thể làm một cái gì đó như thế này:

Stream
    .of(throwable.getStackTrace())
    .map(StackTraceElement::toString)
    .collect(Collectors.joining("\n"));

Nó sẽ lấy một loạt các phần tử theo dõi ngăn xếp, chuyển đổi chúng thành chuỗi và tham gia vào chuỗi đa dòng.


2
Giải pháp này đang xóa tin nhắn và bỏ qua mọi dấu vết của phụ huynh
judovana

3

Oneliner của tôi để chuyển đổi dấu vết ngăn xếp thành chuỗi nhiều dòng kèm theo:

Stream.of(e.getStackTrace()).map((a) -> a.toString()).collect(Collectors.joining("\n", "[", "]"))

Dễ dàng chuyển đến logger "như hiện tại".


Bạn nhận được một cái gì đó khác với ở printStackTrace()đây bạn sẽ mất: 1) Ngoại lệ đã bị ném; 2) Nguyên nhân và stacktrace của họ
valijon

Sự khác biệt là khá mong đợi, vì chuyển đổi printStackTrace()không bao giờ là một phần của câu hỏi.
Andrey Lebedenko

2

Nếu bạn không muốn sử dụng thư viện bên ngoài và bạn không phát triển cho Android , bạn có thể tạo phương thức 'tiện ích mở rộng' như thế này:

public static String getStackTraceString(Throwable e) {
    return getStackTraceString(e, "");
}

private static String getStackTraceString(Throwable e, String indent) {
    StringBuilder sb = new StringBuilder();
    sb.append(e.toString());
    sb.append("\n");

    StackTraceElement[] stack = e.getStackTrace();
    if (stack != null) {
        for (StackTraceElement stackTraceElement : stack) {
            sb.append(indent);
            sb.append("\tat ");
            sb.append(stackTraceElement.toString());
            sb.append("\n");
        }
    }

    Throwable[] suppressedExceptions = e.getSuppressed();
    // Print suppressed exceptions indented one level deeper.
    if (suppressedExceptions != null) {
        for (Throwable throwable : suppressedExceptions) {
            sb.append(indent);
            sb.append("\tSuppressed: ");
            sb.append(getStackTraceString(throwable, indent + "\t"));
        }
    }

    Throwable cause = e.getCause();
    if (cause != null) {
        sb.append(indent);
        sb.append("Caused by: ");
        sb.append(getStackTraceString(cause, indent));
    }

    return sb.toString();
}

2

Câu hỏi cũ, nhưng tôi chỉ muốn thêm trường hợp đặc biệt mà bạn không muốn in tất cả ngăn xếp , bằng cách xóa một số phần bạn không thực sự quan tâm, ngoại trừ các lớp hoặc gói nhất định.

Thay vì PrintWritersử dụng một SelectivePrintWriter:

// This filters out this package and up.
String packageNameToFilter = "org.springframework";

StringWriter sw = new StringWriter();
PrintWriter pw = new SelectivePrintWriter(sw, packageNameToFilter);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); 
System.out.println(sStackTrace);

Trường hợp SelectivePrintWriterlớp được đưa ra bởi:

public class SelectivePrintWriter extends PrintWriter {
    private boolean on = true;
    private static final String AT = "\tat";
    private String internal;

    public SelectivePrintWriter(Writer out, String packageOrClassName) {
        super(out);
        internal = "\tat " + packageOrClassName;
    }

    public void println(Object obj) {
        if (obj instanceof String) {
            String txt = (String) obj;
            if (!txt.startsWith(AT)) on = true;
            else if (txt.startsWith(internal)) on = false;
            if (on) super.println(txt);
        } else {
            super.println(obj);
        }
    }
}

Xin lưu ý rằng lớp này có thể dễ dàng được điều chỉnh để lọc ra theo Regex containshoặc các tiêu chí khác. Cũng lưu ý rằng nó phụ thuộc vào Throwablechi tiết thực hiện (không có khả năng thay đổi, nhưng vẫn còn).


1
Vâng, điều này hoạt động tốt và thực sự là một ý tưởng hữu ích.
gil.fernandes

2
 import java.io.PrintWriter;
import java.io.StringWriter;

public class PrintStackTrace {

    public static void main(String[] args) {

        try {
            int division = 0 / 0;
        } catch (ArithmeticException e) {
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            String exceptionAsString = sw.toString();
            System.out.println(exceptionAsString);
        }
    }
}

Khi bạn chạy chương trình, đầu ra sẽ tương tự:

java.lang.ArithmeticException: / by zero
at PrintStackTrace.main(PrintStackTrace.java:9)

1

Tôi tự hỏi tại sao không ai nhắc đến ExceptionUtils.getStackFrames(exception)

Đối với tôi, đó là cách thuận tiện nhất để kết xuất stacktrace với tất cả các nguyên nhân của nó đến cùng:

String.join("\n", ExceptionUtils.getStackFrames(exception));

0

Cảnh báo: Điều này có thể hơi lạc đề, nhưng ồ ...;)

Tôi không biết lý do áp phích ban đầu là vì muốn theo dõi ngăn xếp dưới dạng chuỗi ở vị trí đầu tiên. Khi theo dõi ngăn xếp sẽ kết thúc trong một SLF4J / Logback LOG, nhưng không có ngoại lệ nào hoặc nên được ném ở đây những gì tôi làm:

public void remove(List<String> ids) {
    if(ids == null || ids.isEmpty()) {
        LOG.warn(
            "An empty list (or null) was passed to {}.remove(List). " +
            "Clearly, this call is unneccessary, the caller should " + 
            "avoid making it. A stacktrace follows.", 
            getClass().getName(),
            new Throwable ("Stacktrace")
        );

        return;
    }

    // actual work, remove stuff
}

Tôi thích nó bởi vì nó không yêu cầu một thư viện bên ngoài (trừ phần phụ trợ đăng nhập của bạn, tất nhiên sẽ luôn ở vị trí hầu hết thời gian).


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.