簡體   English   中英

Log4J - 如何記錄導入庫中捕獲的異常?

[英]Log4J - how to log an exception caught in an imported library?

我是Log4J v.1.2.15的新用戶,因為我的一位朋友使我相信其優於控制台或其他形式的日志記錄。 但是,當我做一些測試時,我遇到了一個讓我思考的測試用例。 這就是我所做的:

  1. 我已經配置了屬性,添加了2個appender,一個ConsoleAppender和一個RollingFileAppender
  2. 我使用我的主類創建了一個新的日志實例: Logger mainLogger = Logger.getLogger(Main.class);
  3. 我把這個通用的,手工制作的java utils集合放在一個名為MyUtils.jar的庫中,添加到我的主應用程序的類路徑中。 在主應用程序中,我從MyUtils.jar調用了一個靜態方法。 此方法有一個try-catch {}塊,並在那里處理異常,使用System.err打印堆棧跟蹤。 現在,使用我的IDE和ConsoleAppender ,我能夠發現問題,但是,事件未記錄在我的文件日志中。 這里有兩個問題需要解答: a。 我目前正在使用mainLogger來記錄我應用程序的所有類中的事件。 這是一個好習慣嗎? 或者我應該為X類使用X記錄器實例? 我該怎么做才能記錄我的導入中已經捕獲的錯誤? 這可能聽起來微不足道,但我使用了Object foo = MyLibrary.composeObjectFoo() ,並且該方法內部與此示例類似:

     public static Object composeObjectFoo() { try { .....statements..... . . // something stupid here int a = 100/0; //an AritmethicException will be thrown } catch Exception(e) { e.printStackTrace(); } } 

謝謝你的回答,請原諒這篇文章的長度......


我建議記錄一些關於日志記錄的事情:

  1. 切勿使用System.out.println()System.err.println()e.printStackTrace() 而是使用記錄器。 您可以將記錄器配置為打印到stdout或stderr,更不用說過濾掉不重要的信息了。 更加靈活。
  2. 最佳做法是在每個類中創建一個可以生成您想要記錄的事件的記錄器,並使用該類創建記錄器名稱(例如Logger.getLogger(Main.class) )。 通過執行此操作,您可以使用所有這些唯一的記錄器名稱來微調日志過濾。 例如,您可以將A類設置為debug ,將B類設置為info如果需要)。
  3. 使用像slf4j這樣的記錄器抽象層(我真的很喜歡這個)或者commons-logging 這將允許您更改記錄器實現,而無需完成所有代碼並更改您登錄的每個位置。

關於例外:

我還建議您閱讀一些關於異常處理最佳實踐的內容。 每個人都會爭論什么是“最好的”,但是所有人都應該同意你應該做的不僅僅是讓一切都泄漏到main() 我喜歡這篇文章的內容

您可以在主類中更改System.out和System.err以打印采用打印內容的流並將其傳遞給記錄器。 它聽起來有點復雜,但它已經在開源項目中完成(例如JBoss有一個實現),所以你可以從那里得到它。

我做了一個合乎邏輯的事情..我已經從我的Utils類中刪除了try-> catch {}塊。 現在生成的異常被主應用程序捕獲並記錄。 真棒! 但是......有沒有保證在使用第三方創建的libs / utils時情況不會重演?

您無法記錄導入庫中捕獲的異常。 您無法將代碼添加到導入的庫中。 一旦它被抓住,你就完成了。 您可以期待的最好的是導入的庫重新拋出異常並讓您有機會記錄某些內容。

我想知道導入的庫的質量,它不會記錄並寫入控制台。 這不是一個好的設計概念。

我不喜歡主類做日志記錄的想法。 你的直覺很好,但你的實施卻不是。 記錄是一個跨領域的問題,應該使用面向方面的編程來完成。

一種。 我目前正在使用mainLogger來記錄我應用程序的所有類中的事件。 這是一個好習慣嗎? 或者我應該為X類使用X記錄器實例?

創建和使用多個Logger通常是一個更好的主意。 這使您(或稍后有人)通過日志記錄配置更好地控制日志記錄級別等。 但我不一定建議在每個類中創建一個(靜態)Logger實例。

我該怎么做才能記錄我的導入中已經捕獲的錯誤?

您無法做到這一點......除了徹底檢查導入的代碼庫以改進其內部錯誤報告和日志記錄。

另一方面,如果您要創建可能在其他地方重用的庫代碼,則應注意獲取錯誤報告和正確記錄。 特別是,清理不當使用System.errprintStackTrace()等。 使用日志記錄抽象層也是一個好主意,這樣您就不會為集成庫的人員帶來問題。

好的,在更多文檔之后,我遇到了這個解決方案,記錄所有內容,無論源代碼是否在您的其他代碼中:

Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread t, Throwable exc) {
              //do something about it
              }
        });

這樣,我能夠捕獲並報告導入庫中發生的異常狀態,但未處理或重新調整。 這就是愚蠢的事情

   public double computeValue(int val){
      double a = 15/val;
     return a;
   }

和val為0,生成ArithmeticException,而不是拋出而不是捕獲。

暫無
暫無

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

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