Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中记录更好的异常信息_Java_Design Patterns_Exception_Exception Handling - Fatal编程技术网

在Java中记录更好的异常信息

在Java中记录更好的异常信息,java,design-patterns,exception,exception-handling,Java,Design Patterns,Exception,Exception Handling,我正在使用Spring、Hibernate和其他一些库(包括用于日志记录的ApacheLog4j)开发一个更大的JavaWeb应用程序。我正在进行的一个项目是重写代码遗留区域(我没有编写!)中的大量异常,以提供更合理的信息。典型的异常块如下所示: try { //Some Hibernate business here } catch (Exception e) { //Yes, Exception. That's not just me being general. I find th

我正在使用Spring、Hibernate和其他一些库(包括用于日志记录的ApacheLog4j)开发一个更大的JavaWeb应用程序。我正在进行的一个项目是重写代码遗留区域(我没有编写!)中的大量异常,以提供更合理的信息。典型的异常块如下所示:

try {
  //Some Hibernate business here
}
catch (Exception e) {   //Yes, Exception. That's not just me being general. I find this especially frustrating.
  log4j.error("Fail to XXXXXX");   //again, real
  throw new MyException();
}
try {
  //Some Hibernate business here
}
catch (Exception e) {   //Yes, Exception.  That's not just me being general
  log4j.error("Fail to XXXXXX", e);   //again, real
  throw new MyException(e);
}
正如您所猜测的,这会导致一些具有挑战性的日志。我正在寻找一种标准的方法来从这些异常中获得更好的信息。如果有帮助的话,它们中的大多数都会包装Hibernate调用。这是一个与我刚才写的类似的典型块:

try {
    myList.add( ((myClass) commonService.getRecordByTableId(myClass.class, ID)).toString() );
} catch (ServiceException e) {
    log4j.error("Failed to retrieve record from table myClass for id " + ID);
    e.printStackTrace();
}

在这里,我从数据库中提取一条记录并将其添加到列表中。在catch块中,我记录我认为是关于
try
块正在做什么的合理消息,并打印堆栈跟踪。所以,我的问题是:一般来说,为了获得更好的错误诊断信息,我还可以/应该做些什么吗?

是的,在第一块中,应该是这样的:

try {
  //Some Hibernate business here
}
catch (Exception e) {   //Yes, Exception. That's not just me being general. I find this especially frustrating.
  log4j.error("Fail to XXXXXX");   //again, real
  throw new MyException();
}
try {
  //Some Hibernate business here
}
catch (Exception e) {   //Yes, Exception.  That's not just me being general
  log4j.error("Fail to XXXXXX", e);   //again, real
  throw new MyException(e);
}
Java允许您链接异常,因此您应该这样做。此外,当使用Log4J时,您还可以发送异常,这样它也会在日志中打印异常堆栈跟踪。

printStackTrace()
不会将跟踪添加到日志中。将异常提供给log4j会将其打印到您的日志文件中,其中上下文有意义:

log4j.error("Failed to retrieve record from table myClass for id " + ID, e);

在异常处理中,日志记录和重新抛出是一种流行的反模式。你不应该那样做。您需要决定是捕获异常,然后正确处理它(包括日志记录),还是不捕获它并允许它传递到更高的级别(或者如果它是选中的异常,则在运行时异常中重新刷新/包装它)

如果您这样做(log+rethrow),那么上游代码就无法知道您已经记录了异常,因此同一异常可能会被记录两次或更多次,这取决于异常必须经过的层数,以及任意决定记录并重新抛出它的层数。这将使阅读日志和理解日志成为一场彻头彻尾的噩梦

此外,您可能会争辩说,抛出和捕获异常是代价高昂的操作,所有这些捕获和重新抛出都无助于提高运行时的性能

因此,如果您选择实际处理异常,那么接受它不是正确的方法(即使您记录了一些消息)。至少,您需要记录跟踪:

log4j.error("Failed to retrieve record from table myClass for id " + ID, e);

除了其他人提到的以外,还有几件事:

  • 利用不同的日志记录级别:信息;警告;等等
  • 从#1开始,我将放弃那些printStackTrace()调用。如果要在控制台中记录错误,请通过记录器进行记录。这样,即使是在控制台上,也可以获得过滤级别的好处

  • +1.如果可以的话,我也会加分。我已经厌倦了看到一个堆栈跟踪有几个“回声”之前。是的,正如我。令人惊讶的是,有多少“认真”的开发人员认为日志记录和重放是一个足够好的处理大多数异常。+ 1,良好的调用。在这个项目中发生的很多事情让我非常难过,我正在努力使它成形达尔索,我喜欢反模式这个词。