it-swarm.com.de

Wie sendet man einen Stacktrace an log4j?

Angenommen, Sie fangen eine Ausnahme und erhalten Folgendes in der Standardausgabe (z. B. auf der Konsole), wenn Sie ein e.printStackTrace () ausführen:

Java.io.FileNotFoundException: so.txt
        at Java.io.FileInputStream.<init>(FileInputStream.Java)
        at ExTest.readMyFile(ExTest.Java:19)
        at ExTest.main(ExTest.Java:7)

Jetzt möchte ich dies stattdessen an einen Logger wie log4j senden, um Folgendes zu erhalten:

31947 [AWT-EventQueue-0] ERROR Java.io.FileNotFoundException: so.txt
32204 [AWT-EventQueue-0] ERROR    at Java.io.FileInputStream.<init>(FileInputStream.Java)
32235 [AWT-EventQueue-0] ERROR    at ExTest.readMyFile(ExTest.Java:19)
32370 [AWT-EventQueue-0] ERROR    at ExTest.main(ExTest.Java:7)

Wie kann ich das machen?

try {
   ...
} catch (Exception e) {
    final String s;
    ...  // <-- What goes here?
    log.error( s );
}
143
SyntaxT3rr0r

Sie übergeben die Ausnahme direkt an den Logger, z.

try {
   ...
} catch (Exception e) {
    log.error( "failed!", e );
}

Es ist Aufgabe von log4j, die Stapelablaufverfolgung wiederzugeben.

239
skaffman

Wenn Sie einen Stacktrace ohne Ausnahme protokollieren möchten, tun Sie dies einfach: 

String message = "";

for(StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {                         
    message = message + System.lineSeparator() + stackTraceElement.toString();
}   
log.warn("Something weird happened. I will print the the complete stacktrace even if we have no exception just to help you find the cause" + message);
7
borjab

Sie können den Stack-Trace auch als Zeichenfolge über ExceptionUtils.getStackTrace abrufen.

Siehe: ExceptionUtils.Java

Ich benutze es nur für log.debug, um log.error einfach zu halten.

7
ktsujister

Diese Antwort kann sich nicht auf die gestellte Frage beziehen, sondern auf den Titel der Frage. 

public class ThrowableTest {

    public static void main(String[] args) {

        Throwable createdBy = new Throwable("Created at main()");
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        PrintWriter pw = new PrintWriter(os);
        createdBy.printStackTrace(pw);
        try {
            pw.close();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        logger.debug(os.toString());
    }
}

OR

public static String getStackTrace (Throwable t)
{
    StringWriter stringWriter = new StringWriter();
    PrintWriter  printWriter  = new PrintWriter(stringWriter);
    t.printStackTrace(printWriter);
    printWriter.close();    //surprise no IO exception here
    try {
        stringWriter.close();
    }
    catch (IOException e) {
    }
    return stringWriter.toString();
}

OR

StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for(StackTraceElement stackTrace: stackTraceElements){
    logger.debug(stackTrace.getClassName()+ "  "+ stackTrace.getMethodName()+" "+stackTrace.getLineNumber());
}
2

Nur weil es mir passiert ist und nützlich sein kann ... Wenn Sie das tun

try {
   ...
} catch (Exception e) {
    log.error( "failed! {}", e );
}

sie erhalten den Header der Ausnahme und nicht den gesamten Stacktrace. Weil der Logger denken wird, dass Sie eine Zeichenkette übergeben. Tun Sie es ohne {}, wie Skaffman gesagt hat

2
iberbeu

Die Antwort von Skaffman ist definitiv die richtige Antwort. Alle Logger-Methoden wie error(), warn(), info(), debug() nehmen Throwable als zweiten Parameter:

try {
...
 } catch (Exception e) {
logger.error("error: ", e);
}

Sie können Stacktrace jedoch auch als String extrahieren. Manchmal kann es nützlich sein, wenn Sie die Formatierungsfunktion mit dem Platzhalter "{}" nutzen möchten - siehe Methode void info(String var1, Object... var2); In diesem Fall sagen Sie, Sie haben einen Stacktrace-String als Zeichenfolge.

try {
...
 } catch (Exception e) {
String stacktrace = TextUtils.getStacktrace(e);
logger.error("error occurred for usename {} and group {}, details: {}",username, group, stacktrace);
}

Dadurch werden die parametrisierte Nachricht und der Stacktrace am Ende genauso ausgegeben wie für die Methode: logger.error("error: ", e);

Ich habe tatsächlich eine Open-Source-Bibliothek geschrieben, die ein Hilfsprogramm zum Extrahieren eines Stacktraces als String mit einer Option zum intelligenten Herausfiltern von Rauschen aus Stacktrace enthält. D.h. Wenn Sie das Paketpräfix angeben, an dem Sie an dem extrahierten Stacktrace interessiert sind, wird dies aus einigen irrelevanten Teilen herausgefiltert und Sie erhalten sehr konservierte Informationen. Hier ist der Link zu dem Artikel, in dem erläutert wird, welche Dienstprogramme in der Bibliothek vorhanden sind und wo sie zu beziehen sind (sowohl als Maven-Artefakte als auch als Git-Quellen) und wie sie verwendet werden. Open-Source-Java-Bibliothek mit Stack-Trace-Filterung, Silent String-Analyse von Unicode-Konverter und Versionsvergleich Siehe Abschnitt "Stacktrace-Rauschfilter"

2
Michael Gantman
Try this:

catch (Throwable t) {
    logger.error("any message" + t);
    StackTraceElement[] s = t.getStackTrace();
    for(StackTraceElement e : s){
        logger.error("\tat " + e);
    }   
}

Sie können den folgenden Code verwenden:

import org.Apache.logging.log4j.Logger;
import org.Apache.logging.log4j.LogManager;

public class LogWriterUtility {
    Logger log;

    public LogWriterUtility(Class<?> clazz) {
        log = LogManager.getLogger(clazz);
    }

public void errorWithAnalysis( Exception exception) {

        String message="No Message on error";
        StackTraceElement[] stackTrace = exception.getStackTrace();
        if(stackTrace!=null && stackTrace.length>0) {
            message="";
            for (StackTraceElement e : stackTrace) {
                message += "\n" + e.toString();
            }
        }
        log.error(message);


    }

}

Hier können Sie einfach anrufen: LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);

Damit wird stackTrace in Ihr Protokoll geschrieben.

0

dies wäre gut. Log4j Fehler-/Ausnahmeprotokollierung - lesbar durch Splunk/andere Protokollierung/Überwachung s/w. alles ist die Form eines Schlüsselwertpaares log4j würde die Stack-Ablaufverfolgung von Exception obj e erhalten.

    try {
          ---
          ---
    } catch (Exception e) {
        log.error("api_name={} method={} _message=\"error description.\" msg={}", 
                  new Object[]{"api_name", "method_name", e.getMessage(), e});
    }
0
src3369