java trace exception get ¿Cómo puedo convertir un seguimiento de pila en una cadena?




13 Answers

Utilice Throwable.printStackTrace (PrintWriter pw) para enviar el seguimiento de la pila a un escritor apropiado.

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);
java exception full stack trace

¿Cuál es la forma más fácil de convertir el resultado de Throwable.getStackTrace() en una cadena que representa el seguimiento de pila?




Si está desarrollando para Android, una forma mucho más fácil es usar esto:

import android.util.Log;

String stackTrace = Log.getStackTraceString(exception); 

El formato es el mismo que getStacktrace, por ejemplo,

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)






Inspirado por @Brian Agnew:

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



Aquí hay una versión que se puede copiar y pegar directamente en el código:

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

O bien, en un bloque catch.

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



Imprima el seguimiento de pila en un PrintStream, luego conviértalo en una cadena

// ...

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

    System.out.println(str);
}



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



El hábil ataque al primer grupo de comentarios fue muy divertido, pero realmente depende de lo que estés tratando de hacer. Si aún no tiene la biblioteca correcta, entonces 3 líneas de código (como en la respuesta de D. Wroblewski) son perfectas. OTOH, si ya tiene la biblioteca apache.commons (como la mayoría de los proyectos grandes), entonces la respuesta de Amar es más corta. De acuerdo, puede llevarle diez minutos obtener la biblioteca e instalarla correctamente (menos de uno si sabe lo que está haciendo). Pero el reloj no se detiene, por lo que es posible que no tenga tiempo de sobra. Jarek Przygódzki tuvo una advertencia interesante: "Si no necesita excepciones anidadas".

¿Pero qué pasa si necesito los rastros de pila completa, anidados y todo? En ese caso, el secreto es usar getFullStackTrace de apache.common (consulte http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29 )

Salvó mi tocino. Gracias, Amar, por la pista!




Código de 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();
}

La diferencia con las otras respuestas es que utiliza autoFlush en el PrintWriter .




Si está utilizando Java 8, intente esto

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

Puede encontrar el código para la función getStackTrace () proporcionado por Throwable.java como:

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

y para StackTraceElement, se suministra a String como:

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

Tan solo únase al StackTraceElement con "\ n"




Si no desea utilizar una biblioteca externa y no está desarrollando para Android , puede crear un método de 'extensión' como este:

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



Mi oneliner para convertir el seguimiento de pila a la cadena de multilínea adjunta:

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

Fácil de pasar al registrador "tal cual".




Use exp.printStackTrace() para mostrar la pila de su excepción.

try {
   int zero = 1 - 1;
   int a = 1/zero;
} catch (Exception e) {
    e.printStackTrace();
}



Related