如何使用java的Logger类记录堆栈跟踪

时间:2015-07-14 19:01:43

标签: java logging stack-trace java.util.logging

我正在使用Java的Logger类。我想将ex.printStackTrace()传递给Logger.log(loglevel, String),但printStackTrace()会返回void。所以我无法传递和打印异常的堆栈跟踪。

有什么方法可以将void转换为String,还是有其他方法可以打印整个堆栈的异常跟踪?

11 个答案:

答案 0 :(得分:28)

您需要了解void实际上是nothingness。你无法转换什么都不是。您可能最终将void打印为字符串,但(相信我),您不希望这样。

我认为你在寻找的是

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

这将使用您配置的记录器打印错误消息。有关更多详细信息,您可以查看Exception#getMessage()

的java文档

答案 1 :(得分:4)

另一种选择是:

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

log.error("Exception : "+ExceptionUtils.getFullStackTrace(e));

答案 2 :(得分:2)

您可以使用getStackTrace()方法获取StackTraceElements数组,并从那里生成一个String。否则,如果只是最终的错误消息就足够了,请使用Makoto建议的getMessage()方法。

要从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");

答案 3 :(得分:0)

正如Makoto所说,你可能想要做一个ex.getMessage()。

为进一步澄清,void表示没有任何回复。你无法投入任何东西:)

答案 4 :(得分:0)

您可以使用下面的方法将stacktrace转换为String。如果e是异常对象

StringWriter stringWriter= new StringWriter();
PrintWriter printWriter= new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
String stackTraceAsString= stringWriter.toString(); 

答案 5 :(得分:0)

有一个重载的printStackTrace方法,它接受PrintWriter。

你可以做这样的事情

Writer buffer = new StringWriter();
PrintWriter pw = new PrintWriter(buffer);
ex.printStackTrace(pw);
Logger.log(loglevel, buffer.toString());

答案 6 :(得分:0)

谢谢大家。我可以使用

记录堆栈跟踪详细信息
LOGGER.log(Level.INFO, ex.getMessage(),ex);
//ex is my exception object

答案 7 :(得分:0)

使用以下格式,您可以获得堆栈跟踪:

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

此模式的重点是%6 $ s。它将打印堆栈跟踪。

答案 8 :(得分:0)

您还可以使用apache库中或日志语句下方的ExceptionUtils

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

答案 9 :(得分:0)

如果需要在不引发异常的情况下查看堆栈跟踪,则可以使用 ExceptionUtils

String stackTrace = ExceptionUtils.getStackTrace(new Exception("YourMessage"));
log.error(stackTrace);

答案 10 :(得分:0)

之前的建议似乎都只是将堆栈跟踪放在日志中,而没有在每一行前面加上记录器详细信息。下面我的建议是处理堆栈跟踪元素并将每一行格式化为记录器行:

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
    }
}

堆栈跟踪的每一行都以“(stacktrace)”为前缀。这样做的好处是可以在转储日志文件时将它们过滤掉,或者能够轻松找到它们。