[英]Logging better exception information in Java
我正在開發一個帶有Spring,Hibernate和其他一些庫的大型Java Web應用程序,包括用於日志記錄的Apache log4j。 我正在進行的項目之一是重寫代碼中遺留區域(我沒寫過!)的大量異常,以提供更明智的信息。 典型的異常塊如下所示:
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();
}
你可以猜到,這會產生一些具有挑戰性的日志。 我正在尋找一種標准方法來從這些例外中獲得更好的信息。 如果有幫助的話,大多數都會包裝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
塊正在做什么的合理消息,並打印堆棧跟蹤。 所以,我的問題是:為了獲得診斷錯誤的更好信息,我還能做什么/應該做些什么呢?
在異常處理中, 記錄和重新投擲是一種流行的反模式 。 你不應該這樣做。 您需要決定捕獲異常,然后正確處理它(包括日志記錄),或者不捕獲它並允許它傳遞到更高級別(或者重新拋出它/將它包裝在運行時異常中,如果它是一個經過檢查的異常)。
如果你這樣做(log + rethrow),那么上游代碼就無法知道你已經記錄了異常,因此相同的異常可能會被記錄兩次或更多次,這取決於異常需要多少層通過,以及任意決定記錄並重新拋出它的層。 這將使閱讀日志並使它們成為一個完整的噩夢。
此外,您可能會認為拋出和捕獲異常是昂貴的操作,所有這些捕獲和重新拋出都無助於您在運行時的性能。
因此,如果您選擇實際處理異常,那么吞咽它就不是正確的方法(即使您記錄了一些消息)。 至少,您需要記錄跟蹤:
log4j.error("Failed to retrieve record from table myClass for id " + ID, e);
printStackTrace()
不會將跟蹤添加到您的日志中。 向log4j提供異常會將其打印到上下文有意義的日志文件中:
log4j.error("Failed to retrieve record from table myClass for id " + ID, e);
是的,在第一個區塊,應該是這樣的:
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時,您還可以發送異常,以便它也會在日志中打印異常堆棧跟蹤。
除了別人提到的東西之外還有幾件事:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.