Как я могу преобразовать трассировку стека в строку? - PullRequest
1380 голосов
/ 19 июля 2009

Какой самый простой способ преобразовать результат Throwable.getStackTrace() в строку, изображающую трассировку стека?

Ответы [ 29 ]

11 голосов
/ 26 декабря 2017
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});
11 голосов
/ 11 мая 2011

Печать трассировки стека в строку

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.

11 голосов
/ 23 апреля 2018

Распечатать трассировку стека в PrintStream, а затем преобразовать его в строку

// ...

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

    System.out.println(str);
}
10 голосов
/ 14 сентября 2017
private String getCurrentStackTraceString() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    return Arrays.stream(stackTrace).map(StackTraceElement::toString)
            .collect(Collectors.joining("\n"));
}
9 голосов
/ 10 марта 2017

Котлин

Расширение класса Throwable даст вам свойство String error.stackTraceString:

val Throwable.stackTraceString: String
  get() {
    val sw = StringWriter()
    val pw = PrintWriter(sw)
    this.printStackTrace(pw)
    return sw.toString()
  }
9 голосов
/ 07 июля 2015

Код от 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();
}

Разница с другими ответами в том, что использует autoFlush на PrintWriter.

9 голосов
/ 15 апреля 2014

Умный снайпер в первом наборе комментариев был очень забавным, но это действительно зависит от того, что вы пытаетесь сделать. Если у вас еще нет правильной библиотеки, то 3 строки кода (как в ответе Д. Вроблевского) идеальны. OTOH, если у вас уже есть библиотека apache.commons (как и большинство крупных проектов), то ответ Амара будет короче. ОК, вам может потребоваться десять минут, чтобы получить библиотеку и установить ее правильно (меньше, чем один, если вы знаете, что делаете). Но часы тикают, поэтому у вас может не быть свободного времени. У Ярека Пшигодзки была интересная оговорка: «Если вам не нужны вложенные исключения».

Но что, если мне нужно нужны полные трассы стека, вложенные и все? В этом случае секрет заключается в использовании getFullStackTrace apache.common (см. http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29)

Это спасло мой бекон. Спасибо, Амар, за подсказку!

6 голосов
/ 07 июня 2016

Без 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 удерживается при печати на 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 голосов
/ 10 апреля 2018

если вы используете Java 8, попробуйте это

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

Вы можете найти код для функции getStackTrace (), предоставляемой Throwable.java, как:

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

и для StackTraceElement он предоставляет строку как:

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

Так что просто присоединитесь к StackTraceElement с "\ n"

4 голосов
/ 15 июля 2016

описание ответа Гала, в котором также будут указаны причины исключения:

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