如何将堆栈跟踪转换为字符串?

发布于 2024-07-27 20:11:35 字数 61 浏览 8 评论 0 原文

将 Throwable.getStackTrace() 的结果转换为描述堆栈跟踪的字符串的最简单方法是什么?

What is the easiest way to convert the result of Throwable.getStackTrace() to a string that depicts the stacktrace?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

豆芽 2024-08-03 20:11:35

使用 Throwable.printStackTrace(PrintWriter pw) 将堆栈跟踪发送到适当的编写器。

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);

Use Throwable.printStackTrace(PrintWriter pw) to send the stack trace to an appropriate writer.

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);
梦毁影碎の 2024-08-03 20:11:35

可以使用以下方法将Exception堆栈跟踪转换为String。 这个类在 Apache commons-lang 中可用,它是最常见的依赖库,具有许多流行的开源代码

org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(可抛出)

One can use the following method to convert an Exception stack trace to String. This class is available in Apache commons-lang which is most common dependent library with many popular open sources

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

∞梦里开花 2024-08-03 20:11:35

这应该有效:

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

This should work:

StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
云柯 2024-08-03 20:11:35

如果您正在为 Android 开发,一个更简单的方法是使用这个:

import android.util.Log;

String stackTrace = Log.getStackTraceString(exception); 

格式与 getStacktrace 相同,例如

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

If you are developing for Android, a far easier way is to use this:

import android.util.Log;

String stackTrace = Log.getStackTraceString(exception); 

The format is the same as getStacktrace, for e.g.

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)
甜味拾荒者 2024-08-03 20:11:35

Guava 的 Throwables

如果您有实际的 Throwable 实例,Google Guava 提供Throwables.getStackTraceAsString()< /代码>

示例:

String s = Throwables.getStackTraceAsString ( myException ) ;

这在幕后使用了printStackTrace,因此它输出一个递归的、修剪的堆栈跟踪(即,原因链中多个原因共有的帧仅打印一次) 。

Guava's Throwables class

If you have the actual Throwable instance, Google Guava provides Throwables.getStackTraceAsString().

Example:

String s = Throwables.getStackTraceAsString ( myException ) ;

This uses printStackTrace under the covers so it outputs a recurisve, trimmed stack trace (i.e., one where frames common to multiple causes in the cause chain are printed only once).

傾城如夢未必闌珊 2024-08-03 20:11:35

警告:不包括原因(这通常是有用的位!)

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

WARNING: Does not include cause (which is usually the useful bit!)

public String stackTraceToString(Throwable e) {
    StringBuilder sb = new StringBuilder();
    for (StackTraceElement element : e.getStackTrace()) {
        sb.append(element.toString());
        sb.append("\n");
    }
    return sb.toString();
}
鼻尖触碰 2024-08-03 20:11:35

对我来说,最干净、最简单的方法是:

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

For me the cleanest and easiest way was:

import java.util.Arrays;
Arrays.toString(e.getStackTrace());
月牙弯弯 2024-08-03 20:11:35
public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}
public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}
审判长 2024-08-03 20:11:35

以下代码允许您以 String 格式获取整个 stackTrace,而无需使用 log4J 甚至 java.util.Logger 等 API:

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.
}

The following code allows you to get the entire stackTrace with a String format, without using APIs like log4J or even 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.
}
习惯成性 2024-08-03 20:11:35

将堆栈跟踪打印到 PrintStream,然后将其转换为 String

// ...

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

    System.out.println(str);
}

Print the stack trace to a PrintStream, then convert it to a String:

// ...

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

    System.out.println(str);
}
撩动你心 2024-08-03 20:11:35

这是一个可直接复制粘贴到代码中的版本:

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());

或者,在 catch 块中

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

Here is a version that is copy-pastable directly into code:

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());

Or, in a catch block

} catch (Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    logger.info("Current stack trace is:\n" + sw.toString());
}
反话 2024-08-03 20:11:35
Arrays.toString(thrown.getStackTrace())

是将结果转换为字符串的最简单方法
我在程序中使用它来打印堆栈跟踪

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

Is the easiest way to convert the result into String
I am using this in my program to print the stack trace

LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});
酷遇一生 2024-08-03 20:11:35

Kotlin >= 1.4

使用内置函数 Throwable 上的 stackTraceToString()

科特林 1.4

扩展 Throwable 类将为您提供 String 属性error.stackTraceString

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

Kotlin >= 1.4

Use the built-in function stackTraceToString() on a Throwable.

Kotlin < 1.4

Extending the Throwable class will give you the String property error.stackTraceString:

val Throwable.stackTraceString: String
  get() {
    val sw = StringWriter()
    val pw = PrintWriter(sw)
    this.printStackTrace(pw)
    return sw.toString()
  }
一笑百媚生 2024-08-03 20:11:35

如果您使用的是 Java 8,请尝试此操作,

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

您可以找到 Throwable.java 提供的 getStackTrace() 函数的代码为:

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

以及 StackTraceElement ,它提供了toString(),如下所示:

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

因此只需将StackTraceElement与“\n”连接起来即可。

if you are using Java 8, try this

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

you can find the code for getStackTrace() function provided by Throwable.java as :

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

and for StackTraceElement, it provides toString() as follows:

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

So just join the StackTraceElement with "\n".

话少心凉 2024-08-03 20:11:35

将堆栈跟踪打印到字符串

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);
        }
    }
}

当您想要打印当前线程堆栈跟踪而不创建 Throwable 实例时,它很有用 - 但请注意,创建新的 Throwable 并从那里获取堆栈跟踪实际上比调用 Thread.getStackTrace 更快、更便宜。

Printing stack trace to string

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);
        }
    }
}

It's useful when you want to print the current thread stack trace without creating instance of Throwable - but note that creating new Throwable and getting stack trace from there is actually faster and cheaper than calling Thread.getStackTrace.

早茶月光 2024-08-03 20:11:35
private String getCurrentStackTraceString() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    return Arrays.stream(stackTrace).map(StackTraceElement::toString)
            .collect(Collectors.joining("\n"));
}
private String getCurrentStackTraceString() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    return Arrays.stream(stackTrace).map(StackTraceElement::toString)
            .collect(Collectors.joining("\n"));
}
凯凯我们等你回来 2024-08-03 20:11:35

来自 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();
}

与其他答案的区别在于它使用 autoFlushPrintWriter 上的 code>。

Code from 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();
}

The difference with the other answers is that it uses autoFlush on the PrintWriter.

半步萧音过轻尘 2024-08-03 20:11:35

第一组评论中的巧妙狙击非常有趣,但这实际上取决于您想要做什么。
如果您还没有正确的库,那么 3 行代码(如 D. Wroblewski 的答案)是完美的。
OTOH,如果您已经拥有 apache.commons 库(就像大多数大型项目一样),那么 Amar 的答案会更短。
好的,您可能需要十分钟才能获取该库并正确安装它(如果您知道自己在做什么,则不到一分钟)。 但时间在流逝,所以你可能没有多余的时间。
Jarek Przygódzki 有一个有趣的警告——“如果你不需要嵌套异常”。

但是,如果我确实需要完整的堆栈跟踪(嵌套的等等)怎么办? 在这种情况下,秘密是使用 apache.common 的 getFullStackTrace (请参阅 http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/ lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29

它救了我的命。 谢谢阿马尔的提示!

The clever sniping in the first set of comments was very amusing, but it really depends on what you are trying to do.
If you don't already have the correct library, then 3 lines of code (as in D. Wroblewski's answer) is perfect.
OTOH, if you already have the apache.commons library (as most large projects will), then Amar's answer is shorter.
OK, it might take you ten minutes to get the library and install it correctly (less than one if you know what you're doing). But the clock is ticking, so you may not have the time to spare.
Jarek Przygódzki had an interesting caveat--"If you don't need nested exceptions".

But what if I do need the full stack traces, nested and all? In that case, the secret is to use apache.common's getFullStackTrace (see http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29)

It saved my bacon. Thanks, Amar, for the hint!

浪推晚风 2024-08-03 20:11:35

使用 Java 8 Stream API你可以这样做:

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

它将获取堆栈跟踪元素数组,将它们转换为字符串并连接成多行字符串。

With Java 8 Stream API you can do something like this:

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

It will take array of stack trace elements, convert them to string and join into multiline string.

带刺的爱情 2024-08-03 20:11:35

如果没有java.io.*,它可以像这样完成。

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

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

然后 trace 变量保存您的堆栈跟踪。 输出还保存初始原因,输出与 printStackTrace() 相同,

例如,printStackTrace() 产生:

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)

打印时 trace 字符串保存到标准输出

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)

Without java.io.* it can be done like this.

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

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

And then the trace variable holds your stack trace. Output also holds the initial cause, the output is identical to printStackTrace()

Example, printStackTrace() yields:

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)

The trace String holds, when printed to 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)
扬花落满肩 2024-08-03 20:11:35

对 Gala 答案的扩展,其中还包括异常的原因:

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;
}

an exapansion on Gala's answer that will also include the causes for the exception:

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;
}
三寸金莲 2024-08-03 20:11:35

斯卡拉版本

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

Scala version

def stackTraceToString(e: Exception): String = {
  import java.io.{PrintWriter, StringWriter}
  val sw = new StringWriter()
  e.printStackTrace(new PrintWriter(sw))
  sw.toString
}
剧终人散尽 2024-08-03 20:11:35

如果您不想使用外部库并且不开发 对于 Android,您可以创建一个 '扩展'方法 像这样:

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();
}

If you don't want to use an external library and you're not developing for Android, you could create an 'extension' method like this:

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();
}
独守阴晴ぅ圆缺 2024-08-03 20:11:35

解决方案是将数组的stackTrace转换为字符串数据类型。 请参见以下示例:

import java.util.Arrays;

try{

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

The solution is to convert the stackTrace of array to string data type. See the following example:

import java.util.Arrays;

try{

}catch(Exception ex){
    String stack = Arrays.toString(ex.getStackTrace());
    System.out.println("stack "+ stack);
}
故事↓在人 2024-08-03 20:11:35

我的 oneliner 将堆栈跟踪转换为随附的多行字符串:

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

轻松“按原样”传递给记录器。

My oneliner to convert stack trace to the enclosed multi-line string:

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

Easy to pass to the logger "as is".

为你拒绝所有暧昧 2024-08-03 20:11:35

几个选项

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

  2. 使用 Google Guava lib
    String stackTrace = Throwables.getStackTraceAsString ( myException ) ;

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

Few options

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

  2. Using Google Guava lib
    String stackTrace = Throwables.getStackTraceAsString ( myException ) ;

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

淤浪 2024-08-03 20:11:35
 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);
        }
    }
}

当您运行该程序时,输出将类似于:

java.lang.ArithmeticException: / by zero
at PrintStackTrace.main(PrintStackTrace.java:9)
 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);
        }
    }
}

When you run the program, the output will be something similar:

java.lang.ArithmeticException: / by zero
at PrintStackTrace.main(PrintStackTrace.java:9)
ペ泪落弦音 2024-08-03 20:11:35

我想知道为什么没有人提到 ExceptionUtils.getStackFrames(exception)

对于我来说,这是转储堆栈跟踪及其所有原因的最方便的方法:

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

I wonder why no one mentioned ExceptionUtils.getStackFrames(exception)

For me it's the most convenient way to dump stacktrace with all its causes to the end:

String.join("\n", ExceptionUtils.getStackFrames(exception));
尽揽少女心 2024-08-03 20:11:35

警告:这可能有点偏离主题,但是哦,好吧……;)

我不知道最初的发帖者想要将堆栈跟踪作为字符串的原因是什么。 当堆栈跟踪应该以 SLF4J/Logback LOG 结束,但没有或不应该抛出异常时,我会这样做:

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
}

我喜欢它,因为它不需要外部库(除了您的日志记录后端,它将就位)当然,大多数时候都是如此)。

Warning: This may be a bit off topic, but oh well... ;)

I don't know what the original posters reason was for wanting the stack trace as string in the first place. When the stack trace should end up in an SLF4J/Logback LOG, but no exception was or should be thrown here's what I do:

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
}

I like it because it does not require an external library (other than your logging backend, which will be in place most of the time anyway, of course).

独行侠 2024-08-03 20:11:35

我不久前为此编写了一些方法,所以我想为什么不为此投入两分钱呢。

/** @param stackTraceElements The elements to convert
 * @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements) {
    return stackTraceElementsToStr(stackTraceElements, "\n");
}

/** @param stackTraceElements The elements to convert
 * @param lineSeparator The line separator to use
 * @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
    return stackTraceElementsToStr(stackTraceElements, lineSeparator, "");
}

/** @param stackTraceElements The elements to convert
 * @param lineSeparator The line separator to use
 * @param padding The string to be used at the start of each line
 * @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
    String str = "";
    if(stackTraceElements != null) {
        for(StackTraceElement stackTrace : stackTraceElements) {
            str += padding + (!stackTrace.toString().startsWith("Caused By") ? "\tat " : "") + stackTrace.toString() + lineSeparator;
        }
    }
    return str;
}

/** @param stackTraceElements The elements to convert
 * @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements) {
    return stackTraceCausedByElementsOnlyToStr(stackTraceElements, "\n");
}

/** @param stackTraceElements The elements to convert
 * @param lineSeparator The line separator to use
 * @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
    return stackTraceCausedByElementsOnlyToStr(stackTraceElements, lineSeparator, "");
}

/** @param stackTraceElements The elements to convert
 * @param lineSeparator The line separator to use
 * @param padding The string to be used at the start of each line
 * @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
    String str = "";
    if(stackTraceElements != null) {
        for(StackTraceElement stackTrace : stackTraceElements) {
            str += (!stackTrace.toString().startsWith("Caused By") ? "" : padding + stackTrace.toString() + lineSeparator);
        }
    }
    return str;
}

/** @param e The {@link Throwable} to convert
 * @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e) {
    return throwableToStrNoStackTraces(e, "\n");
}

/** @param e The {@link Throwable} to convert
 * @param lineSeparator The line separator to use
 * @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator) {
    return throwableToStrNoStackTraces(e, lineSeparator, "");
}

/** @param e The {@link Throwable} to convert
 * @param lineSeparator The line separator to use
 * @param padding The string to be used at the start of each line
 * @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator, String padding) {
    if(e == null) {
        return "null";
    }
    String str = e.getClass().getName() + ": ";
    if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
        str += e.getMessage() + lineSeparator;
    } else {
        str += lineSeparator;
    }
    str += padding + stackTraceCausedByElementsOnlyToStr(e.getStackTrace(), lineSeparator, padding);
    for(Throwable suppressed : e.getSuppressed()) {
        str += padding + throwableToStrNoStackTraces(suppressed, lineSeparator, padding + "\t");
    }
    Throwable cause = e.getCause();
    while(cause != null) {
        str += padding + "Caused by:" + lineSeparator + throwableToStrNoStackTraces(e.getCause(), lineSeparator, padding);
        cause = cause.getCause();
    }
    return str;
}

/** @param e The {@link Throwable} to convert
 * @return The resulting String */
public static final String throwableToStr(Throwable e) {
    return throwableToStr(e, "\n");
}

/** @param e The {@link Throwable} to convert
 * @param lineSeparator The line separator to use
 * @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator) {
    return throwableToStr(e, lineSeparator, "");
}

/** @param e The {@link Throwable} to convert
 * @param lineSeparator The line separator to use
 * @param padding The string to be used at the start of each line
 * @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator, String padding) {
    if(e == null) {
        return "null";
    }
    String str = padding + e.getClass().getName() + ": ";
    if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
        str += e.getMessage() + lineSeparator;
    } else {
        str += lineSeparator;
    }
    str += padding + stackTraceElementsToStr(e.getStackTrace(), lineSeparator, padding);
    for(Throwable suppressed : e.getSuppressed()) {
        str += padding + "Suppressed: " + throwableToStr(suppressed, lineSeparator, padding + "\t");
    }
    Throwable cause = e.getCause();
    while(cause != null) {
        str += padding + "Caused by:" + lineSeparator + throwableToStr(e.getCause(), lineSeparator, padding);
        cause = cause.getCause();
    }
    return str;
}

示例:

try(InputStream in = new FileInputStream(file)) {
    ...
} catch(IOException e) {
    String exceptionToString = throwableToStr(e);
    someLoggingUtility.println(exceptionToString);
    ...
}

打印:

java.io.FileNotFoundException: C:\test.txt (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    at com.gmail.br45entei.Example.main(Example.java:32)

I wrote a few methods for this a while ago, so I figured why not throw my two cents at this.

/** @param stackTraceElements The elements to convert
 * @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements) {
    return stackTraceElementsToStr(stackTraceElements, "\n");
}

/** @param stackTraceElements The elements to convert
 * @param lineSeparator The line separator to use
 * @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
    return stackTraceElementsToStr(stackTraceElements, lineSeparator, "");
}

/** @param stackTraceElements The elements to convert
 * @param lineSeparator The line separator to use
 * @param padding The string to be used at the start of each line
 * @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
    String str = "";
    if(stackTraceElements != null) {
        for(StackTraceElement stackTrace : stackTraceElements) {
            str += padding + (!stackTrace.toString().startsWith("Caused By") ? "\tat " : "") + stackTrace.toString() + lineSeparator;
        }
    }
    return str;
}

/** @param stackTraceElements The elements to convert
 * @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements) {
    return stackTraceCausedByElementsOnlyToStr(stackTraceElements, "\n");
}

/** @param stackTraceElements The elements to convert
 * @param lineSeparator The line separator to use
 * @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
    return stackTraceCausedByElementsOnlyToStr(stackTraceElements, lineSeparator, "");
}

/** @param stackTraceElements The elements to convert
 * @param lineSeparator The line separator to use
 * @param padding The string to be used at the start of each line
 * @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
    String str = "";
    if(stackTraceElements != null) {
        for(StackTraceElement stackTrace : stackTraceElements) {
            str += (!stackTrace.toString().startsWith("Caused By") ? "" : padding + stackTrace.toString() + lineSeparator);
        }
    }
    return str;
}

/** @param e The {@link Throwable} to convert
 * @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e) {
    return throwableToStrNoStackTraces(e, "\n");
}

/** @param e The {@link Throwable} to convert
 * @param lineSeparator The line separator to use
 * @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator) {
    return throwableToStrNoStackTraces(e, lineSeparator, "");
}

/** @param e The {@link Throwable} to convert
 * @param lineSeparator The line separator to use
 * @param padding The string to be used at the start of each line
 * @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator, String padding) {
    if(e == null) {
        return "null";
    }
    String str = e.getClass().getName() + ": ";
    if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
        str += e.getMessage() + lineSeparator;
    } else {
        str += lineSeparator;
    }
    str += padding + stackTraceCausedByElementsOnlyToStr(e.getStackTrace(), lineSeparator, padding);
    for(Throwable suppressed : e.getSuppressed()) {
        str += padding + throwableToStrNoStackTraces(suppressed, lineSeparator, padding + "\t");
    }
    Throwable cause = e.getCause();
    while(cause != null) {
        str += padding + "Caused by:" + lineSeparator + throwableToStrNoStackTraces(e.getCause(), lineSeparator, padding);
        cause = cause.getCause();
    }
    return str;
}

/** @param e The {@link Throwable} to convert
 * @return The resulting String */
public static final String throwableToStr(Throwable e) {
    return throwableToStr(e, "\n");
}

/** @param e The {@link Throwable} to convert
 * @param lineSeparator The line separator to use
 * @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator) {
    return throwableToStr(e, lineSeparator, "");
}

/** @param e The {@link Throwable} to convert
 * @param lineSeparator The line separator to use
 * @param padding The string to be used at the start of each line
 * @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator, String padding) {
    if(e == null) {
        return "null";
    }
    String str = padding + e.getClass().getName() + ": ";
    if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
        str += e.getMessage() + lineSeparator;
    } else {
        str += lineSeparator;
    }
    str += padding + stackTraceElementsToStr(e.getStackTrace(), lineSeparator, padding);
    for(Throwable suppressed : e.getSuppressed()) {
        str += padding + "Suppressed: " + throwableToStr(suppressed, lineSeparator, padding + "\t");
    }
    Throwable cause = e.getCause();
    while(cause != null) {
        str += padding + "Caused by:" + lineSeparator + throwableToStr(e.getCause(), lineSeparator, padding);
        cause = cause.getCause();
    }
    return str;
}

Example:

try(InputStream in = new FileInputStream(file)) {
    ...
} catch(IOException e) {
    String exceptionToString = throwableToStr(e);
    someLoggingUtility.println(exceptionToString);
    ...
}

Prints:

java.io.FileNotFoundException: C:\test.txt (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    at com.gmail.br45entei.Example.main(Example.java:32)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文