如何为Java异常记录尽可能多的信息?

Ste*_*ers 55 java methods logging exception stack-trace

在记录异常时,我遇到了一些常见问题.似乎有各种不同类型可以处理.例如,有些包装其他Exceptions,有些根本没有消息 - 只是一种类型.

大多数代码我已经使用或者看到日志异常getMessage()toString(),但这些并不总是捕捉查明问题所需的所有信息-其他方法,如getCause()getStackTrace()有时提供额外的信息.

作为一个例子,我现在在Eclipse Inspect窗口中看到的异常是一个InvocationTargetException.Exception本身没有原因,没有消息,没有堆栈跟踪......但getCause()的目标是InvalidUseOfMatchersException填充这些详细信息.

所以我的问题是:给定一个异常作为输入的任何类型,请提供一个单一的方法,将输出一个格式良好的字符串,其中包含有关异常的所有相关信息(例如可能递归调用getCause()其他东西?)在发布此问题之前我几乎我自己也会捅这个但是真的不想重新发明轮子 - 当然这样的事情必须要多次做过......?

请不要指向任何特定的日志记录或实用程序框架来执行此操作.我正在寻找代码片段而不是库,因为我没有权利在我正在处理的项目上添加外部依赖项,它实际上是记录到网页的一部分而不是文件.如果这是一个从这样的框架中复制代码片段(并归因于它)的情况那很好:-)

flu*_*lup 70

java.util.logging软件包Java SE的标准软件包.它Logger包括一个接受Throwable对象的重载日志方法.它将记录异常堆栈跟踪及其原因.

例如:

import java.util.logging.Level;
import java.util.logging.Logger;

[...]

Logger logger = Logger.getAnonymousLogger();
Exception e1 = new Exception();
Exception e2 = new Exception(e1);
logger.log(Level.SEVERE, "an exception was thrown", e2);
Run Code Online (Sandbox Code Playgroud)

会记录:

SEVERE: an exception was thrown
java.lang.Exception: java.lang.Exception
    at LogStacktrace.main(LogStacktrace.java:21)
Caused by: java.lang.Exception
    at LogStacktrace.main(LogStacktrace.java:20)
Run Code Online (Sandbox Code Playgroud)

在内部,这正是@philipp-wendler建议的顺便说一句.请参阅源代码SimpleFormatter.java.这只是一个更高级别的界面.

  • 请记住,如果您使用自定义格式化程序,则必须特别支持使用Throwables(我只是复制了Oracle代码),否则这将无效. (5认同)

Phi*_*ler 19

提供的printStacktrace()方法有什么问题Throwable(因此每个例外)?它显示了您请求的所有信息,包括根异常的类型,消息和堆栈跟踪以及所有(嵌套)原因.在Java 7中,它甚至向您显示有关try-with-resources语句中可能出现的"被抑制"异常的信息.

当然你不想写System.err,方法的无参数版本,所以改为使用一个可用的重载.

特别是,如果你只想获得一个字符串:

  Exception e = ...
  StringWriter sw = new StringWriter();
  e.printStackTrace(new PrintWriter(sw));
  String exceptionDetails = sw.toString();
Run Code Online (Sandbox Code Playgroud)

如果你碰巧使用了巨大的番石榴库,它提供了一个实用的方法这样做:com.google.common.base.Throwables#getStackTraceAsString(Throwable).


Har*_*apu 11

如果您使用LogBack或SLF4J应该很简单.我这样做如下

//imports
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

//Initialize logger
Logger logger = LoggerFactory.getLogger(<classname>.class);
try {
   //try something
} catch(Exception e){
   //Actual logging of error
   logger.error("some message", e);
}
Run Code Online (Sandbox Code Playgroud)