近小編一直在幫忙學習java的學員調試一些讓人頭大的bug問題實在是差一點就被難到了(調皮一下),小編也才意識到也該和大家說一下如何記錄異常日志對于簡化調試的重要性,小編總結了幾點記錄異常日志的實踐發表在此。大家可以參考一下。
1、記錄技術性異常而不是用戶異常
用戶異常(如:“登錄用戶名已經存在”)除了顯示給用戶,要么什么都別管,要么根本就不是異常(“用戶尚未認證”)。技術性異常(如:“文件存儲不夠,沒法訂閱此產品”)才是你需要調試而為此做出反應的,如果你記錄所有事情很有可能因日志實體太長而不能真正有意義的反映到你所記錄異常日志中。你應該查明日志文件中的每個異常找到其原因(“是bug嗎”),過多的異常將使你草率地對待異常(“額,僅僅是一個普通異常”)。2、把數據存儲在異常中以便更易于記錄
“沒法收取賬戶費用“這樣的異常你應該存儲異常的上下文,就像Junit所做的(“期望…但是得到…”)以便更易于調試。CannotChargeMoneyAccountExceptionMoney(moneyInAccount, Money toCharge, Account account)這段子句可以理解為:“嘗試收取賬戶1234567890 20EUR,但是只有10EUR可用”相對于“扣除失敗”,這使得在之后有意義的方式記錄異常變得更簡單。
3、記錄異常的描述信息
糟糕的例子來自于Sun:ClassCastException不能顯示什么類你想要轉換。 現在甚至可以發現:
final String s = "Hello";
final int x = (Integer) s;
在編譯時就告訴你:
T.java:4: inconvertible types
found : java.lang.String
required: java.lang.Integer
final Integer x = (Integer) s;
在運行期間Java拋出的異常
Exception in thread "main" java.lang.ClassCastException:
java.lang.String cannot be cast to java.lang.Integer
這樣顯得比前者要好
4、輸出導致異常的原因
如果在異常中有一個包裝的方式作為異常的起因,那么記錄所有的原因。一些日志框架已經幫你這樣做了,有些還沒有,因此要確保異常的所有原因記錄在日志文件中,保證所有相關的堆棧追蹤信息的開始處記錄在你的文件中,而不是雜亂無章的。
5、選擇合理的日志級別
如果你的異常危急的,記錄它為Level.CRITICAL,如果你需要確定危急對你來說意味著什么(通常意味著金錢損失),例如如果一個預定功能失效,或者由于技術問題用戶不能注冊,然后你就有一個危急問題需要解決。 監控日志文件中危急的異常,因為你正在蒙受著損失。擁有你自己的異常實現isCritical()或者CRITICALException接口,用封裝類以及正確的日志級別記錄異常到文件中。如果你的日志框架找不到合理的級別,那么創建它。
6、不要記錄后又重新向外拋出
記錄日志后重新拋出異常是一個異常反模式(anti-pattern)。
catch (NoUserException e) {
LOG.error("No user available", e);
throw new UserServiceException("Nouseravailable", e);
}
不要這么做,你的日志文件包含相同的異常好幾次在堆棧級別上,記住僅僅記錄一次。
7、不要使用System.out或者System.err記錄
使用日志框架,它可以比你處理得更好,希望這些規則在處理異常日志時能幫助到你,能使你更容易調試。