173 votes

Comment envoyer une trace de pile à log4j ?

Disons que vous attrapez une exception et obtenez ce qui suit sur la sortie standard (comme, par exemple, la console) si vous faites un e.printStackTrace() :

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

Maintenant je veux envoyer ceci à un logger comme, disons, log4j pour obtenir ce qui suit :

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)

Comment puis-je le faire ?

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

288voto

skaffman Points 197885

Vous passez l'exception directement au logger, par exemple

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

C'est à log4j de rendre la trace de la pile.

14voto

borjab Points 1839

Si vous voulez enregistrer une trace de la pile sans impliquer une exception, il suffit de faire ceci :

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

11voto

ktsujister Points 197

Vous pouvez également obtenir la trace de la pile sous forme de chaîne via ExceptionUtils.getStackTrace. http://commons.apache.org/lang/api-3.0/org/apache/commons/lang3/exception/ExceptionUtils.html

Je l'utilise seulement pour log.debug, pour garder log.error simple.

7voto

iberbeu Points 1191

Juste parce que ça m'est arrivé et que ça peut être utile. Si vous faites ça

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

vous obtiendrez l'en-tête de l'exception et non l'intégralité du suivi de pile. Parce que le logger pensera que vous passez un String. Faites-le sans {} comme l'a dit skaffman

2voto

Kanagavelu Sugumar Points 1206

Cette réponse peut ne pas être liée à la question posée mais au titre de la question.

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

OU

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X