簡體   English   中英

如何使用 java 的 Logger class 記錄堆棧跟蹤

[英]How do I log a stacktrace using java's Logger class

我正在使用 Java 的Logger class。我想將ex.printStackTrace()傳遞給Logger.log(loglevel, String) ,但printStackTrace()返回void 所以我無法傳遞和打印異常的堆棧跟蹤。

有什么方法可以將void轉換為String ,或者是否有任何其他方法可以打印異常的整個堆棧跟蹤?

你需要明白void實際上是nothingness 你不能轉換什么都不是。 您可能最終將void打印為字符串,但是(相信我),您不想要那樣。

我想你正在尋找的是

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

這將使用您配置的記錄器打印錯誤消息。 有關更多詳細信息,您可以查看Exception#getMessage()的 java 文檔

使用java.util.logging.Logger#log(Level, String, Throwable)並傳入ex作為第三個參數,如下所示:

LOGGER.log(Level.INFO, ex.getMessage(), ex);

另一種選擇是:

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

log.error("Exception : " + ExceptionUtils.getStackTrace(exception));

使用以下格式,您可以獲得堆棧跟蹤:

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

此模式中的要點是 %6$s。 它將打印堆棧跟蹤。

您不能將void轉換為String 不存在這種轉換。 void不會返回任何內容,因此您沒有任何價值可檢索。

您可能想要做的是通過ex.getMessage()獲取異常消息。

有一個重載的printStackTrace 方法接收PrintWriter。

你可以做這樣的事情

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

您可以使用getStackTrace()方法獲取 StackTraceElements 數組,並從那里生成一個字符串。 否則,如果只有最終的錯誤消息就足夠了,請使用 Makoto 建議的getMessage()方法。

要從StackTraceElement對象數組中以String獲取堆棧跟蹤,您需要遍歷該數組(取自 JDK7 源代碼):

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

另一種選擇是使用printStackTrace(PrintStream s) ,您可以在其中指定要打印printStackTrace(PrintStream s)位置:

ByteArrayOutputStream out1 = new ByteArrayOutputStream();
PrintStream out2 = new PrintStream(out1);
ex.printStackTrace(out2);
String message = out1.toString("UTF8");

謝謝你們。 我能夠使用記錄堆棧跟蹤詳細信息

LOGGER.log(Level.INFO, ex.getMessage(),ex);
//ex is my exception object

如果你需要看到堆棧跟蹤不拋出異常,您可以使用一個ExceptionUtils。

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

正如 Makoto 所說,你可能想做一個 ex.getMessage()。

進一步澄清, void意味着沒有返回任何內容。 你不能把任何東西都投進去:)

您可以使用下面的方法將堆棧跟蹤轉換為字符串。 如果e是異常對象

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

您還可以使用來自 apache 庫或以下日志語句的 ExceptionUtils

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

之前的建議似乎都只是將堆棧跟蹤放在日志中,而沒有在每一行前面加上記錄器詳細信息。 我下面的建議處理堆棧跟蹤元素並將每一行格式化為記錄器行:

 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)”為前綴。 這樣做的好處是能夠在轉儲日志文件時將它們過濾掉,或者能夠輕松找到它們。

使用 java.util.Arrays 你也可以輕松解決這個問題:

try {
    doSomething();
} catch (Exception e) {
    logger.error(Arrays.toString(e.getStackTrace()));
}

Arrays.toString(Object[] a) 為每個元素調用 Object.toString() 或如果 object 為 null 則返回帶“null”的字符串。元素由逗號和空格分隔。 StackTraceElement 實現了 toString(),因此您從 e.getStackTrace() 獲得的數組可以很好地轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM