如何最简单地将Throwable.getStackTrace()
的结果转换为描述堆栈跟踪的字符串?
如何最简单地将Throwable.getStackTrace()
的结果转换为描述堆栈跟踪的字符串?
虽然这是一个老问题,但我想补充一下特殊情况,即您不想打印整个堆栈,通过删除您实际上不感兴趣的某些部分,排除某些类或包。
可以使用SelectivePrintWriter
而不是PrintWriter
:
// 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);
给定 SelectivePrintWriter
类如下:
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);
}
}
}
Throwable
的实现细节(不太可能改变,但仍需注意)。使用 Kotlin 快捷方式将堆栈跟踪写入现有的 StringBuilder:
此版本非常快,因为它避免了创建临时字符串并在其中复制的过程。
private fun StringBuilder.appendStackTrace(thr: Throwable) =
thr.printStackTrace(object : PrintWriter(StringWriter()) {
override fun println(x: Any?) {
this@appendStackTrace.append(x)
this@appendStackTrace.append('\n')
}
})
你可以这样调用它:
val s = buildString {
append("Some text before the stack trace ...\n")
appendStackTrace(throwable)
append("Some other stuff")
}