Как отправить stacktrace в log4j?
скажем, вы ловите исключение и получаете следующее на стандартном выходе (например, консоль), если вы делаете Эл.печатные():
java.io.FileNotFoundException: so.txt
at java.io.FileInputStream.<init>(FileInputStream.java)
at ExTest.readMyFile(ExTest.java:19)
at ExTest.main(ExTest.java:7)
Теперь я хочу отправить это вместо регистратора, как, скажем, log4j, чтобы получить следующее:
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)
как я могу это сделать?
try {
...
} catch (Exception e) {
final String s;
... // <-- What goes here?
log.error( s );
}
10 ответов:
вы передаете исключение непосредственно регистратору, например
try { ... } catch (Exception e) { log.error( "failed!", e ); }это до log4j, чтобы отобразить трассировку стека.
Если вы хотите зарегистрировать stacktrace без привлечения исключения, просто сделайте это:
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);
вы также можете получить трассировку стека в строку через
ExceptionUtils.getStackTrace.посмотреть: ExceptionUtils.java
Я использую его только для
log.debugсохранитьlog.errorпростой.
этот ответ может быть не связан с заданным вопросом, но связан с названием вопроса.
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()); } }или
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(); }или
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); for(StackTraceElement stackTrace: stackTraceElements){ logger.debug(stackTrace.getClassName()+ " "+ stackTrace.getMethodName()+" "+stackTrace.getLineNumber()); }
ответ от skaffman, безусловно, правильный ответ. Все методы регистратора, такие как
error(),warn(),info(),debug()возьмите Throwable в качестве второго параметра:try { ... } catch (Exception e) { logger.error("error: ", e); }тем не менее, вы можете извлечь stacktrace в виде строки, а также. Иногда это может быть полезно, если вы хотите воспользоваться функцией форматирования с помощью заполнителя "{} " - см. Метод
void info(String var1, Object... var2);в этом случае говорят, что у вас есть stacktrace как строка, то вы можете сделать что-то вроде это:try { ... } catch (Exception e) { String stacktrace = TextUtils.getStacktrace(e); logger.error("error occurred for usename {} and group {}, details: {}",username, group, stacktrace); }это выведет параметризованное сообщение и stacktrace в конце так же, как и для метода:
logger.error("error: ", e);Я на самом деле написал библиотеку с открытым исходным кодом, которая имеет утилиту для извлечения stacktrace в виде строки с возможностью быстро отфильтровать некоторый шум из stacktrace. Т. е. если вы укажете префикс пакета, который вас интересует, ваш извлеченный stacktrace будет отфильтрован из некоторых нерелевантных частей и оставит вас с очень это очень важная информация. Вот ссылка на статью, в которой объясняется, какие утилиты есть в библиотеке и где ее получить (как артефакты maven, так и источники git), а также как ее использовать. библиотека Java с открытым исходным кодом с фильтрацией трассировки стека, бесшумным разбором строк Unicode converter и сравнением версий см. пункт "фильтр шума Stacktrace"
просто потому, что это случилось со мной и может быть полезно. Если вы сделаете это
try { ... } catch (Exception e) { log.error( "failed! {}", e ); }вы получите заголовок исключения, а не весь stacktrace. Потому что регистратор будет думать, что вы передаете строку. Сделайте это без
{}как skaffman сказал
это было бы хорошо log4j ошибка / исключение протоколирования-читаемый splunk / другой журнал / мониторинг s / w. все это форма пары ключ-значение. к log4j бы получить трассировку стека исключения из объекта obj
etry { --- --- } 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); } }
Вы можете использовать код ниже:
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); } }здесь вы можете просто звоните :
LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);он будет печатать stackTrace в вашем журнале.
создать этот
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); } }; } }назовите это в своем коде
StdOutErrLog.tieSystemOutAndErrToLog();
Comments