簡體   English   中英

在Java中記錄更好的異常信息

[英]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時,您還可以發送異常,以便它也會在日志中打印異常堆棧跟蹤。

除了別人提到的東西之外還有幾件事:

  1. 利用不同的日志記錄級別:info; 警告; 等等
  2. 繼#1后,我放棄了那些printStackTrace()調用。 如果要在控制台中記錄錯誤,請通過記錄器執行。 這樣,即使對於控制台,您也可以獲得過濾級別的好處。

暫無
暫無

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

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