Как да регистрирам stacktrace с помощта на класа Logger на Java

Използвам класа Logger на Java. Искам да предам ex.printStackTrace() в Logger.log(loglevel, String), но printStackTrace() връща void. Така че не мога да предам и отпечатам проследяването на стека на изключението.

Има ли някакъв начин, по който мога да преобразувам void в String, или има ли други методи за отпечатване на цялата следа на стека от изключения?


person Surya Joseph    schedule 14.07.2015    source източник
comment
накратко: НЕ, не можете.   -  person Bacteria    schedule 14.07.2015
comment
Разбира се, използвайте това: commons.apache.org/proper/commons-lang/javadocs/api-3.4/org/ от commons-lang3 3.4   -  person EpicPandaForce    schedule 14.07.2015
comment
В какъв вид низова стойност би се превърнало нищо?   -  person user2864740    schedule 14.07.2015


Отговори (13)


Трябва да разберете, че void всъщност е nothingness. Не можете да преобразувате това, което е нищо. В крайна сметка може да отпечатате void като низ, но (повярвайте ми), не искате това.

Мисля, че това, което търсите, е

// assuming ex is your Exception object
logger.error(ex.getMessage(), ex);
// OR
Logger.log(errorLogLevel, ex.getMessage(), ex)

Това ще отпечата съобщението за грешка с помощта на регистратора, който сте конфигурирали. За повече подробности можете да разгледате документите на Java за Изключение#getMessage()

person Saif Asif    schedule 14.07.2015
comment
Благодаря, Сейф Асиф. Сега мога да регистрирам цялото проследяване на стека. - person Surya Joseph; 14.07.2015
comment
logger.error() не е java.util.logging, но няма да гласувам против вас, защото се радвам да открия logger.log(Level, Exception, Supplier). Изглежда, че Oracle са направили java.util.logging.Logger сериозно грозен! Тъй като правеха това, странно е, че не го направиха по-нататък и не създадоха logger.severe(String, Exception) и т.н - person Adam; 11.10.2017
comment
Въпросът изисква решение с помощта на класа Logger на Java. java.util.logging.Logger няма метод, наречен грешка. Гласувах против този отговор само поради това. - person DAB; 28.08.2018
comment
@Adam Съгласен съм, че logger.error() изглежда грозно, но е много четимо и това е начинът, по който се прави в други прости езици като Python, така че не е толкова ужасно лошо. - person DGoiko; 14.03.2019
comment
Това изобщо не отговаря на първоначалното намерение да се отпечата проследяването на стека на регистратор. getMessage() не е създаден за това. - person A. Gille; 22.05.2020
comment
И така, отговорът е: logger.log(Level.SEVERE, ex.getMessage(), ex); - person Kenny; 14.10.2020

Използвайте java.util.logging.Logger#log(Level, String, Throwable) и предайте ex като трети аргумент по този начин:

LOGGER.log(Level.INFO, ex.getMessage(), ex);
person hzpz    schedule 14.07.2015
comment
Не мога да регистрирам проследяване на стека с това, само втория аргумент. - person Panu Haaramo; 13.01.2018
comment
Възможно е да потиснете проследяването на стека чрез промяна на формата на журнала. Кой формататор използвате и как изглежда вашият формат на журнал? - person hzpz; 19.01.2018
comment
Това е истинският отговор на въпроса. - person steinybot; 04.04.2019
comment
@PanuHaaramo Зависи кой формататор използвате. Форматиращият трябва да извика record.getThrown() в format. Разгледайте SimpleFormatter. - person steinybot; 04.04.2019

Също така друга алтернатива би била:

import org.apache.commons.lang3.exception.ExceptionUtils;

log.error("Exception : " + ExceptionUtils.getStackTrace(exception));
person Rutuja    schedule 19.04.2018
comment
Ако имате предвид org.apache.commons.lang3.exception.ExceptionUtils, това е ExceptionUtils.getStackTrace(e) - person JoschJava; 04.09.2018

С формата по-долу можете да имате трасирането на стека:

java.util.logging.SimpleFormatter.format=%1$tF %1$tT [%4$-7s][%2$s] %5$s %6$s%n

Точката в този модел е %6$s. Той ще отпечата проследяването на стека.

person iman    schedule 08.08.2018

Не можете да конвертирате void в String; такова преобразуване не съществува. void не връща нищо обратно, така че нямате стойност за извличане.

Това, което вероятно искате да направите, е вместо това да получите съобщението за изключението чрез ex.getMessage().

person Makoto    schedule 14.07.2015

Има претоварен метод printStackTrace, който приема PrintWriter.

Можете да направите нещо подобно

Writer buffer = new StringWriter();
PrintWriter pw = new PrintWriter(buffer);
ex.printStackTrace(pw);
Logger.log(loglevel, buffer.toString());
person sleeloy    schedule 14.07.2015
comment
Това е най-простият метод IMHO и той наистина отпечатва проследяването на стека, а не само съобщението. - person Marco Sulla; 21.05.2021

Можете да използвате getStackTrace() за получаване на масив от StackTraceElements и генериране на низ от там. В противен случай, ако само последното съобщение за грешка е достатъчно, използвайте метода getMessage(), както е предложено от Makoto.

За да получите проследяването на стека като String от масив от StackTraceElement обекти, трябва да преминете през масива (взет от източника JDK7):

StringBuilder builder = new StringBuilder();
StackTraceElement[] trace = getOurStackTrace();
    for (StackTraceElement traceElement : trace)
        builder.append("\tat " + traceElement + "\n");

Друг вариант е да използвате printStackTrace(PrintStream s), където можете да посочите къде искате да се отпечата следата на стека:

ByteArrayOutputStream out1 = new ByteArrayOutputStream();
PrintStream out2 = new PrintStream(out1);
ex.printStackTrace(out2);
String message = out1.toString("UTF8");
person Chthonic Project    schedule 14.07.2015
comment
Просто използвайте библиотеката Apache Commons ExceptionUtils; няма нужда да преоткривате колелото - person beresfordt; 14.07.2015
comment
1. String message = out1.toString("UTF8"); - грешка при компилиране, очаквани са 0 параметри, но е получен 1 2. Работи правилно out2.out.toString. В случай out2.toString -› 'PrintStream@hash' - person Nikita; 20.11.2019

Можете да използвате ExceptionUtils, ако трябва да видите stacktrace, без да хвърляте изключение.

String stackTrace = ExceptionUtils.getStackTrace(new Exception("YourMessage"));
log.error(stackTrace);
person Anton Tevs    schedule 23.10.2020

Както казва Макото, вероятно искате да направите ex.getMessage().

За допълнително пояснение, void означава, че не е върнато нищо. Не можеш да вложиш нищо в нещо :)

person kotakotakota    schedule 14.07.2015
comment
Той иска проследяване на стека, а не само съобщението. - person Oliv; 17.05.2019

МОЖЕТЕ да конвертирате stacktrace в String, като използвате по-долу. Ако e е обектът за изключение

StringWriter stringWriter= new StringWriter();
PrintWriter printWriter= new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
String stackTraceAsString= stringWriter.toString(); 
person Amit.rk3    schedule 14.07.2015

Благодаря на всички ви. Мога да регистрирам подробностите за проследяване на стека с помощта на

LOGGER.log(Level.INFO, ex.getMessage(),ex);
//ex is my exception object
person Surya Joseph    schedule 14.07.2015

Можете също да използвате ExceptionUtils от библиотеката на apache или по-долу лог отчет

    try{
      doSomething();
    }
    catch(Exception e){
    log.error("Exception in method doSomething ",e);
    }
person Saurabh    schedule 28.10.2019

Всички предишни предложения изглежда просто поставят проследяването на стека в дневника, без да поставят пред всеки ред подробностите за регистратора. Моето предложение по-долу обработва елементите за проследяване на стека и форматира всеки ред като ред за регистратор:

log.error("{}", e.toString());
StackTraceElement[] stElements = e.getStackTrace();

log.error("(stacktrace) {}", e.toString());

for (StackTraceElement ste: stElements) {
    log.error("(stacktrace)     at {}.{}({}.java:{})", 
        new Object[] {ste.getClassName(), ste.getMethodName(), 
                      ste.getClassName(), ste.getLineNumber()});
}

Throwable thisThrowable = e;
boolean causedBy = true;
while (causedBy) {
    Throwable throwable = thisThrowable.getCause();
    if (throwable != null) {
        log.error("(stacktrace) Caused by: {}", throwable.toString());
        stElements = throwable.getStackTrace();
        for (StackTraceElement ste: stElements) {
            log.error("(stacktrace)     at {}.{}({}.java:{})", 
                 new Object[] {ste.getClassName(), ste.getMethodName(),                    
                               ste.getClassName(), ste.getLineNumber()});
        }
        thisThrowable = throwable;  // For the next caused-by check
    } else {
        log.error("(stacktrace) No Caused-by Exception");
        causedBy = false;  // No more caused-by Throwables, so end the loop
    }
}

Всеки ред от проследяването на стека има префикс (следа на стека). Това има предимството да можете да ги филтрирате, когато изхвърляте регистрационни файлове или да можете да ги намирате лесно.

person hairysocks    schedule 18.06.2021