java logging log4j stack-trace

java - ¿Cómo enviar una stacktrace a log4j?



logging stack-trace (9)

Crea esta 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 String string) { logger.info(string); } public void println(final String string) { logger.info(string); } }; } }

Llamar esto en tu código

StdOutErrLog.tieSystemOutAndErrToLog();

Supongamos que capta una excepción y obtiene lo siguiente en el resultado estándar (como, por ejemplo, la consola) si realiza 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)

Ahora quiero enviar esto a un registrador como, por ejemplo, log4j para obtener lo siguiente:

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)

¿Cómo puedo hacer esto?

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


Esta respuesta puede no estar relacionada con la pregunta, sino con el título de la pregunta.

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

O

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

O

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


La respuesta de skaffman es definitivamente la respuesta correcta. Todos los métodos de registro como error() , warn() , info() , debug() toman Throwable como un segundo parámetro:

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

Sin embargo, también puedes extraer stacktrace como String. A veces puede ser útil si desea aprovechar la función de formateo con el marcador de posición "{}" - consulte la void info(String var1, Object... var2); método void info(String var1, Object... var2); En este caso, di que tienes una stacktrace como String, entonces puedes hacer algo como esto:

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

Esto imprimirá el mensaje parametrizado y el stacktrace al final de la misma forma que lo hace para el método: logger.error("error: ", e);

De hecho, escribí una biblioteca de código abierto que tiene una Utilidad para la extracción de una pila de caracteres como una Cadena con una opción para filtrar de forma inteligente el ruido de stacktrace. Es decir, si especifica el prefijo del paquete que le interesa, su stack stack extraído se eliminará de algunas partes irrelevantes y le dejará información muy detallada. Aquí está el enlace al artículo que explica qué utilidades tiene la biblioteca y dónde obtenerla (tanto como artefactos convencionales como fuentes de git) y cómo usarla también. Biblioteca Java de código abierto con filtrado de seguimiento de pila, Silent String analizando convertidor Unicode y comparación de versión Consulte el párrafo " Filtro de ruido Stacktrace "


Si desea registrar una stacktrace sin involucrar una excepción simplemente haga esto:

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


Solo porque me pasó a mí y puede ser útil. Si haces esto

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

obtendrá el encabezado de la excepción y no toda la stacktrace. Porque el registrador pensará que estás pasando un String. Hazlo sin {} como dijo skaffman


También puede obtener el seguimiento de la pila como cadena a través de ExceptionUtils.getStackTrace .

Ver: ExceptionUtils.java

Lo uso solo para log.debug , para mantener log.error simple.


Usted pasa la excepción directamente al registrador, por ejemplo

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

Depende de log4j renderizar la pila.


esto sería un buen log4j error / exception logging - legible por splunk / other logging / monitoring s / w. todo es una forma de par clave-valor. log4j obtendría el seguimiento de la pila desde 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); } }