Comment envoyer une stacktrace à log4j?

Supposons que vous récupériez une exception et obtenez ce qui suit sur la sortie standard (par exemple, la console) si vous faites un e.printStackTrace () :

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

Maintenant, je veux plutôt envoyer ceci à un enregistreur comme, par exemple, 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.(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 faire ceci?

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

Vous transmettez l’exception directement à l’enregistreur, par exemple

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

C’est à log4j de rendre la trace de la stack.

Si vous souhaitez enregistrer une trace de stack sans impliquer une exception, procédez comme suit:

 Ssortingng message = ""; for(StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) { message = message + System.lineSeparator() + stackTraceElement.toSsortingng(); } 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); 

Vous pouvez également obtenir une trace de stack sous forme de chaîne via ExceptionUtils.getStackTrace .

Voir: ExceptionUtils.java

Je l’utilise uniquement pour log.debug , pour garder log.error simple.

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(Ssortingng[] 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.toSsortingng()); } } 

OU

 public static Ssortingng getStackTrace (Throwable t) { SsortingngWriter ssortingngWriter = new SsortingngWriter(); PrintWriter printWriter = new PrintWriter(ssortingngWriter); t.printStackTrace(printWriter); printWriter.close(); //surprise no IO exception here try { ssortingngWriter.close(); } catch (IOException e) { } return ssortingngWriter.toSsortingng(); } 

OU

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

La réponse de skaffman est sans aucun doute la bonne réponse. Toutes les méthodes de journalisation telles que error() , warn() , info() , debug() prennent en second lieu Throwable:

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

Cependant, vous pouvez également extraire stacktrace en tant que chaîne. Parfois, cela peut être utile si vous souhaitez profiter de la fonctionnalité de formatage à l’aide de l’espace réservé “{}” – voir void info(Ssortingng var1, Object... var2); méthode void info(Ssortingng var1, Object... var2); Dans ce cas, disons que vous avez une stacktrace en tant que Ssortingng, vous pouvez alors faire quelque chose comme ceci:

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

Cela va imprimer le message paramétré et le stacktrace à la fin de la même manière que pour la méthode: logger.error("error: ", e);

J’ai en fait écrit une bibliothèque open source qui possède un utilitaire permettant d’extraire une stacktrace en tant que Ssortingng avec une option permettant de filtrer intelligemment certains parasites du stacktrace. Par exemple, si vous spécifiez le préfixe de paquet qui vous intéresse, votre stacktrace extraite sera filtrée à partir de certaines parties non pertinentes et vous laissera des informations très consignées. Voici le lien vers l’article qui explique quels utilitaires la bibliothèque possède et où l’obtenir (à la fois sous forme d’artefacts Maven et de sources Git) et comment l’utiliser également. Bibliothèque Java Open Source avec filtrage de trace de stack, parsing de chaîne Silent Ssortingng Convertisseur Unicode et comparaison de version Voir le paragraphe ” Filtre de bruit Stacktrace

Juste parce que cela m’est arrivé et peut être utile. Si tu fais ça

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

vous obtiendrez l’en-tête de l’exception et non la stack complète. Parce que le logger pensera que vous transmettez une chaîne. Faites-le sans {} comme dit skaffman

ce serait une bonne erreur log4j / journalisation des exceptions – lisible par splunk / autre journalisation / surveillance s / w. tout est forme de paire clé-valeur. log4j obtiendrait la trace de la stack depuis Exception obj e

  try { --- --- } catch (Exception e) { log.error("api_name={} method={} _message=\"error description.\" msg={}", new Object[]{"api_name", "method_name", e.getMessage(), e}); } 
 Try this: catch (Throwable t) { logger.error("any message" + t); StackTraceElement[] s = t.getStackTrace(); for(StackTraceElement e : s){ logger.error("\tat " + e); } } 

Vous pouvez utiliser le code ci-dessous:

 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) { Ssortingng message="No Message on error"; StackTraceElement[] stackTrace = exception.getStackTrace(); if(stackTrace!=null && stackTrace.length>0) { message=""; for (StackTraceElement e : stackTrace) { message += "\n" + e.toSsortingng(); } } log.error(message); } } 

Ici, vous pouvez simplement appeler: LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);

Il imprimera stackTrace dans votre journal.

Créez cette class :

 public class StdOutErrLog { private static final Logger logger = Logger.getLogger(StdOutErrLog.class); public static void tieSystemOutAndErrToLog() { System.setOut(createLoggingProxy(System.out)); System.setErr(createLoggingProxy(System.err)); } public static PrintStream createLoggingProxy(final PrintStream realPrintStream) { return new PrintStream(realPrintStream) { public void print(final Ssortingng ssortingng) { logger.info(ssortingng); } public void println(final Ssortingng ssortingng) { logger.info(ssortingng); } }; } } 

Appelez ceci dans votre code

 StdOutErrLog.tieSystemOutAndErrToLog();