天天看點

阿裡巴巴 Java 開發手冊之異常日志(二)-------我的經驗二、異常日志

說明:無法通過預檢查的異常除外,如在解析一個外部傳來的字元串形式數字時,通過catch numberformatexception來實作。 正例:if (obj != null) {...} 反例:try { obj.method() } catch (nullpointerexception e) {...}

說明:本規約明确防止npe是調用者的責任。即使被調用方法傳回空集合或者空對象,對調用者來說,也并非高枕無憂,必須考慮到遠端調用失敗,運作時異常等場景傳回null的情況。

正例:可以使用jdk8的optional類來防止npe問題。(說實話,這個optional沒用過)

說明:關于rpc方法傳回方式使用result方式的理由:

1)使用抛異常傳回方式,調用方如果沒有捕獲到就會産生運作時錯誤。

2)如果不加棧資訊,隻是new自定義異常,加入自己的了解的error message,對于調用端解決問題的幫助不會太多。如果加了棧資訊,在頻繁調用出錯的情況下,資料序列化和傳輸的性能損耗也是問題。

正例:一個類中有多個public方法,都需要進行數行相同的參數校驗操作,這個時候請抽取:private boolean checkparam(dto dto) {...}(雖然這樣說沒錯,但有時候秉着不改别人代碼的原則很多時候都是複制代碼,我覺得這個壞習慣該改了)

import org.slf4j.logger;

import org.slf4j.loggerfactory;

private static final logger logger = loggerfactory.getlogger(abc.class);

正例:mppserver應用中單獨監控時區轉換異常,如: mppserver_monitor_timezoneconvert.log

說明:推薦對日志進行分類,錯誤日志和業務日志盡量分開存放,便于開發人員檢視,也便于通過日志對系統進行及時監控。

說明:logger.debug("processing trade with id: " + id + " symbol: " + symbol); 如果日志級别是warn,上述日志不會列印,但是會執行字元串拼接操作,如果symbol是對象,會執行tostring()方法,浪費了系統資源,執行了上述操作,最終日志卻沒有列印。

正例:(條件)

if (logger.isdebugenabled()) {

logger.debug("processing trade with id: " + id + " symbol: " + symbol);

}

正例:(占位符)

logger.debug("processing trade with id: {} symbol : {} ", id, symbol);

正例:< logger name="com.taobao.dubbo.config" additivity="false">

正例:logger.error(各類參數或者對象tostring + "_" + e.getmessage(), e);

記錄日志時請思考:這些日志真的有人看嗎?看到這條日志你能做什麼?能不能給問題排查帶來好處?