Как отправить трассировку стека в log4j? - PullRequest
147 голосов
/ 03 декабря 2010

Допустим, вы перехватываете исключение и получаете следующее на стандартном выводе (например, на консоли), если выполняете 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 );
}

Ответы [ 10 ]

248 голосов
/ 03 декабря 2010

Вы передаете исключение непосредственно в регистратор, например,

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

Это до log4j для рендеринга трассировки стека.

8 голосов
/ 28 августа 2014

Если вы хотите записать трассировку стека без исключения, просто сделайте это:

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);
8 голосов
/ 23 февраля 2012

Вы также можете получить трассировку стека в виде строки через ExceptionUtils.getStackTrace.

См .: ExceptionUtils.java

Я использую его только для log.debug, чтобы сохранитьlog.error просто.

2 голосов
/ 04 июля 2017

Ответ от Скаффмана, безусловно, правильный ответ. Все методы ведения журнала, такие как error(), warn(), info(), debug(), принимают Throwable в качестве второго параметра:

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

Тем не менее, вы также можете извлекать трассировку стека в виде строки. Иногда это может быть полезно, если вы хотите воспользоваться возможностью форматирования с использованием заполнителя "{}" - см. Метод void info(String var1, Object... var2); В этом случае, скажем, у вас есть трассировка стека как String, тогда вы можете сделать что-то вроде этого:

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

Это выведет параметризованное сообщение и трассировку стека в конце так же, как и для метода: logger.error("error: ", e);

На самом деле я написал библиотеку с открытым исходным кодом, в которой есть утилита для извлечения трассировки стека в виде строки с возможностью интеллектуальной фильтрации некоторого шума из трассировки стека. То есть если вы укажете префикс пакета, который вас интересует в извлеченной трассировке стека, он будет отфильтрован из не относящихся к делу частей и предоставит вам очень обобщенную информацию. Вот ссылка на статью, которая объясняет, какие утилиты есть в библиотеке и где ее взять (как в виде артефактов maven, так и в источниках git) и как ее использовать. Java-библиотека с открытым исходным кодом с фильтрацией трассировки стека, анализ Unicode для анализа Silent String и сравнение версий См. Параграф « Фильтр шумов Stacktrace »

2 голосов
/ 30 июня 2014

Только потому, что это случилось со мной и может быть полезным. Если вы сделаете это

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

вы получите заголовок исключения, а не всю трассировку стека. Потому что регистратор будет думать, что вы передаете строку. Сделай это без {}, как сказал скаффман

2 голосов
/ 28 сентября 2013

Этот ответ может быть не связан с заданным вопросом, но связан с названием вопроса.

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());
}
0 голосов
/ 02 августа 2018

Вы можете использовать приведенный ниже код:

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 в ваш журнал.

0 голосов
/ 14 октября 2017
Try this:

catch (Throwable t) {
    logger.error("any message" + t);
    StackTraceElement[] s = t.getStackTrace();
    for(StackTraceElement e : s){
        logger.error("\tat " + e);
    }   
}
0 голосов
/ 10 августа 2017

это было бы хорошо log4j протоколирование ошибок / исключений - читаемое с помощью splunk / других журналов / мониторинга s / w.все является формой пары ключ-значение.log4j получит трассировку стека из исключительной ситуации obj e

    try {
          ---
          ---
    } catch (Exception e) {
        log.error("api_name={} method={} _message=\"error description.\" msg={}", 
                  new Object[]{"api_name", "method_name", e.getMessage(), e});
    }
0 голосов
/ 15 апреля 2013

Создать это 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();
...