Ответ 1
Вы передаете исключение непосредственно в регистратор, например.
try {
...
} catch (Exception e) {
log.error( "failed!", e );
}
Это до log4j для отображения трассировки стека.
Предположим, что вы обнаруживаете исключение и получаете на стандартном выходе (например, консоль) следующее: если вы используете 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)
Теперь я хочу отправить это вместо регистратора, например, 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 );
}
Вы передаете исключение непосредственно в регистратор, например.
try {
...
} catch (Exception e) {
log.error( "failed!", e );
}
Это до log4j для отображения трассировки стека.
Вы также можете получить трассировку стека в виде строки через ExceptionUtils.getStackTrace
.
Смотрите: ExceptionUtils.java
Я использую его только для log.debug
, чтобы сохранить log.error
простым.
Если вы хотите зарегистрировать 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);
Этот ответ может быть не связан с вопросом, но связан с заголовком вопроса.
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());
}
Просто потому, что это случилось со мной и может быть полезно. Если вы сделаете это
try {
...
} catch (Exception e) {
log.error( "failed! {}", e );
}
вы получите заголовок исключения, а не весь стек. Поскольку регистратор будет считать, что вы передаете строку.
Сделайте это без {}
, как сказал скаффман
Ответ от скаффмана определенно правильный ответ. Все методы регистратора, такие как error()
, warn()
, info()
, debug()
принимают Throwable в качестве второго параметра:
try {
...
} catch (Exception e) {
logger.error("error: ", e);
}
Однако вы также можете извлечь stacktrace как String. Иногда это может быть полезно, если вы хотите воспользоваться функцией форматирования, используя "{}" placeholder - см. Метод void info(String var1, Object... var2);
В этом случае скажите, что у вас есть стекtrace как String, тогда вы можете сделать что-то вроде этого:
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 как String с возможностью изящно отфильтровать некоторый шум из stacktrace. То есть если вы укажете префикс пакета, который вам интересен в вашем извлеченном стеке, будет отфильтрован из некоторых нерелевантных частей и оставит вас с очень интересной информацией. Вот ссылка на статью, в которой объясняются, какие утилиты есть в библиотеке и где ее получить (как артефакты maven, так и источники git), и как их использовать. Библиотека Java с открытым исходным кодом с фильтрацией трассировки стека, синтаксический анализ строк Unicode-конвертер и сравнение версий См. параграф " Фильтр шума Stacktrace"
это было бы хорошо log4j error/exception logging - читается с помощью splunk/other logging/monitoring s/w. все это форма пары ключ-значение.
log4j получит трассировку стека из 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);
}
}
Вы можете использовать приведенный ниже код:
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 в ваш журнал.
В Log4j 2 вы можете использовать Logger.catching(), чтобы регистрировать трассировку стека из обнаруженного исключения.
try {
String msg = messages[messages.length];
logger.error("An exception should have been thrown");
} catch (Exception ex) {
logger.catching(ex);
}
Создайте этот 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();