如何使用 java 的记录器 class 记录堆栈跟踪
How do I log a stacktrace using java's Logger class
我正在使用 Java 的 Logger
class。我想将 ex.printStackTrace()
传递给 Logger.log(loglevel, String)
,但是 printStackTrace()
returns void
。所以我无法传递和打印异常的堆栈跟踪。
有什么方法可以将 void
转换为 String
,或者是否有任何其他方法可以打印异常的整个堆栈跟踪?
您无法将 void
转换为 String
;不存在这样的转换。 void
没有 return 任何东西 回来,所以你没有检索的价值。
您可能想要做的是通过 ex.getMessage()
.
获取异常消息
正如 Makoto 所说,您可能想做一个 ex.getMessage()。
为了进一步说明,void
表示没有返回任何内容。你不能把任何东西都投进去:)
你需要明白void
实际上是nothingness
。你无法转换什么都不是。您可能最终将 void
打印为字符串,但是(相信我),您不希望这样。
我想你要找的是
// assuming ex is your Exception object
logger.error(ex.getMessage(), ex);
// OR
Logger.log(errorLogLevel, ex.getMessage(), ex)
这将使用您配置的记录器打印错误消息。有关详细信息,您可以查看 Exception#getMessage()
的 java 文档
您可以使用 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)
,您可以在其中指定要打印堆栈跟踪的位置:
ByteArrayOutputStream out1 = new ByteArrayOutputStream();
PrintStream out2 = new PrintStream(out1);
ex.printStackTrace(out2);
String message = out1.toString("UTF8");
使用 java.util.logging.Logger#log(Level, String, Throwable)
并传入 ex
作为第三个参数,如下所示:
LOGGER.log(Level.INFO, ex.getMessage(), ex);
您可以使用以下方法将堆栈跟踪转换为字符串。如果 e
是异常对象
StringWriter stringWriter= new StringWriter();
PrintWriter printWriter= new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
String stackTraceAsString= stringWriter.toString();
有一个重载的 printStackTrace 方法接收 PrintWriter。
你可以这样做
Writer buffer = new StringWriter();
PrintWriter pw = new PrintWriter(buffer);
ex.printStackTrace(pw);
Logger.log(loglevel, buffer.toString());
谢谢大家。我可以使用
记录堆栈跟踪详细信息
LOGGER.log(Level.INFO, ex.getMessage(),ex);
//ex is my exception object
另一种选择是:
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。它将打印堆栈跟踪。
您还可以使用 apache 库中的 ExceptionUtils 或下面的日志语句
try{
doSomething();
}
catch(Exception e){
log.error("Exception in method doSomething ",e);
}
如果您需要在不抛出异常的情况下查看堆栈跟踪,您可以使用 ExceptionUtils。
String stackTrace = ExceptionUtils.getStackTrace(new Exception("YourMessage"));
log.error(stackTrace);
之前的建议似乎都只是将堆栈跟踪放在日志中,而没有在每行前面加上记录器详细信息。我在下面的建议是处理堆栈跟踪元素并将每一行格式化为记录器行:
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 的 Logger
class。我想将 ex.printStackTrace()
传递给 Logger.log(loglevel, String)
,但是 printStackTrace()
returns void
。所以我无法传递和打印异常的堆栈跟踪。
有什么方法可以将 void
转换为 String
,或者是否有任何其他方法可以打印异常的整个堆栈跟踪?
您无法将 void
转换为 String
;不存在这样的转换。 void
没有 return 任何东西 回来,所以你没有检索的价值。
您可能想要做的是通过 ex.getMessage()
.
正如 Makoto 所说,您可能想做一个 ex.getMessage()。
为了进一步说明,void
表示没有返回任何内容。你不能把任何东西都投进去:)
你需要明白void
实际上是nothingness
。你无法转换什么都不是。您可能最终将 void
打印为字符串,但是(相信我),您不希望这样。
我想你要找的是
// assuming ex is your Exception object
logger.error(ex.getMessage(), ex);
// OR
Logger.log(errorLogLevel, ex.getMessage(), ex)
这将使用您配置的记录器打印错误消息。有关详细信息,您可以查看 Exception#getMessage()
的 java 文档您可以使用 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)
,您可以在其中指定要打印堆栈跟踪的位置:
ByteArrayOutputStream out1 = new ByteArrayOutputStream();
PrintStream out2 = new PrintStream(out1);
ex.printStackTrace(out2);
String message = out1.toString("UTF8");
使用 java.util.logging.Logger#log(Level, String, Throwable)
并传入 ex
作为第三个参数,如下所示:
LOGGER.log(Level.INFO, ex.getMessage(), ex);
您可以使用以下方法将堆栈跟踪转换为字符串。如果 e
是异常对象
StringWriter stringWriter= new StringWriter();
PrintWriter printWriter= new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
String stackTraceAsString= stringWriter.toString();
有一个重载的 printStackTrace 方法接收 PrintWriter。
你可以这样做
Writer buffer = new StringWriter();
PrintWriter pw = new PrintWriter(buffer);
ex.printStackTrace(pw);
Logger.log(loglevel, buffer.toString());
谢谢大家。我可以使用
记录堆栈跟踪详细信息LOGGER.log(Level.INFO, ex.getMessage(),ex);
//ex is my exception object
另一种选择是:
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。它将打印堆栈跟踪。
您还可以使用 apache 库中的 ExceptionUtils 或下面的日志语句
try{
doSomething();
}
catch(Exception e){
log.error("Exception in method doSomething ",e);
}
如果您需要在不抛出异常的情况下查看堆栈跟踪,您可以使用 ExceptionUtils。
String stackTrace = ExceptionUtils.getStackTrace(new Exception("YourMessage"));
log.error(stackTrace);
之前的建议似乎都只是将堆栈跟踪放在日志中,而没有在每行前面加上记录器详细信息。我在下面的建议是处理堆栈跟踪元素并将每一行格式化为记录器行:
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)”为前缀。这样做的好处是可以在转储日志文件时过滤掉它们,或者可以很容易地找到它们。