異常日志

二、異常日志

(一)異常處理

1.【強(qiáng)制】不要捕獲Java類庫(kù)中定義的繼承自RuntimeException的運(yùn)行時(shí)異常類,如:

IndexOutOfBoundsException / NullPointerException,這類異常由程序員預(yù)檢查來(lái)規(guī)避,保

證程序健壯性。

正例:if(obj != null) {...}

反例:try { obj.method() } catch(NullPointerException e){…}

2.【強(qiáng)制】異常不要用來(lái)做流程控制,條件控制,因?yàn)楫惓5奶幚硇时葪l件分支低。

3.【強(qiáng)制】對(duì)大段代碼進(jìn)行try-catch,這是不負(fù)責(zé)任的表現(xiàn)。catch時(shí)請(qǐng)分清穩(wěn)定代碼和非穩(wěn) 定代碼,穩(wěn)定代碼指的是無(wú)論如何不會(huì)出錯(cuò)的代碼。對(duì)于非穩(wěn)定代碼的catch盡可能進(jìn)行區(qū)分

異常類型,再做對(duì)應(yīng)的異常處理。

4.【強(qiáng)制】捕獲異常是為了處理它,不要捕獲了卻什么都不處理而拋棄之,如果不想處理它,請(qǐng)

將該異常拋給它的調(diào)用者。最外層的業(yè)務(wù)使用者,必須處理異常,將其轉(zhuǎn)化為用戶可以理解的

內(nèi)容。

5.【強(qiáng)制】有try塊放到了事務(wù)代碼中,catch異常后,如果需要回滾事務(wù),一定要注意手動(dòng)回 滾事務(wù)。

6.【強(qiáng)制】finally塊必須對(duì)資源對(duì)象、流對(duì)象進(jìn)行關(guān)閉,有異常也要做try-catch。 說(shuō)明:如果JDK7,可以使用try-with-resources方法。

7.【強(qiáng)制】不能在finally塊中使用return,finally塊中的return返回后方法結(jié)束執(zhí)行,不 會(huì)再執(zhí)行try塊中的return語(yǔ)句。

8.【強(qiáng)制】捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。 說(shuō)明:如果預(yù)期拋的是繡球,實(shí)際接到的是鉛球,就會(huì)產(chǎn)生意外情況。

9.【推薦】方法的返回值可以為null,不強(qiáng)制返回空集合,或者空對(duì)象等,必須添加注釋充分 說(shuō)明什么情況下會(huì)返回null值。調(diào)用方需要進(jìn)行null判斷防止NPE問(wèn)題。

說(shuō)明:本規(guī)約明確防止NPE是調(diào)用者的責(zé)任。即使被調(diào)用方法返回空集合或者空對(duì)象,對(duì)調(diào)用

者來(lái)說(shuō),也并非高枕無(wú)憂,必須考慮到遠(yuǎn)程調(diào)用失敗,運(yùn)行時(shí)異常等場(chǎng)景返回null的情況。

10.【推薦】防止NPE,是程序員的基本修養(yǎng),注意NPE產(chǎn)生的場(chǎng)景:

1) 返回類型為包裝數(shù)據(jù)類型,有可能是null,返回int值時(shí)注意判空。

阿里巴巴JAVA開發(fā)手冊(cè)

19 / 32

反例:public int f(){ return Integer對(duì)象},如果為null,自動(dòng)解箱拋NPE。

2) 數(shù)據(jù)庫(kù)的查詢結(jié)果可能為null。

3) 集合里的元素即使isNotEmpty,取出的數(shù)據(jù)元素也可能為null。

4) 遠(yuǎn)程調(diào)用返回對(duì)象,一律要求進(jìn)行NPE判斷。

5) 對(duì)于Session中獲取的數(shù)據(jù),建議NPE檢查,避免空指針。

6) 級(jí)聯(lián)調(diào)用obj.getA().getB().getC();一連串調(diào)用,易產(chǎn)生NPE。

11.【推薦】在代碼中使用“拋異常”還是“返回錯(cuò)誤碼”,對(duì)于公司外的http/api開放接口必

須使用“錯(cuò)誤碼”;而應(yīng)用內(nèi)部推薦異常拋出;跨應(yīng)用間RPC調(diào)用優(yōu)先考慮使用Result方式,

封裝isSuccess、“錯(cuò)誤碼”、“錯(cuò)誤簡(jiǎn)短信息”。

說(shuō)明:關(guān)于RPC方法返回方式使用Result方式的理由:

1)使用拋異常返回方式,調(diào)用方如果沒(méi)有捕獲到就會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤。

2)如果不加棧信息,只是new自定義異常,加入自己的理解的error message,對(duì)于調(diào)用

端解決問(wèn)題的幫助不會(huì)太多。如果加了棧信息,在頻繁調(diào)用出錯(cuò)的情況下,數(shù)據(jù)序列化和傳輸

的性能損耗也是問(wèn)題。

12.【推薦】定義時(shí)區(qū)分unchecked / checked異常,避免直接使用RuntimeException拋出,更

不允許拋出Exception或者Throwable,應(yīng)使用有業(yè)務(wù)含義的自定義異常。推薦業(yè)界已定義過(guò)

的自定義異常,如:DaoException / ServiceException等。

13.【參考】避免出現(xiàn)重復(fù)的代碼(Don’t Repeat Yourself),即DRY原則。

說(shuō)明:隨意復(fù)制和粘貼代碼,必然會(huì)導(dǎo)致代碼的重復(fù),在以后需要修改時(shí),需要修改所有的副

本,容易遺漏。必要時(shí)抽取共性方法,或者抽象公共類,甚至是共用模塊。

正例:一個(gè)類中有多個(gè)public方法,都需要進(jìn)行數(shù)行相同的參數(shù)校驗(yàn)操作,這個(gè)時(shí)候請(qǐng)抽取:

private boolean checkParam(DTO dto){...} ?(二)日志規(guī)約

1.【強(qiáng)制】應(yīng)用中不可直接使用日志系統(tǒng)(Log4j、Logback)中的API,而應(yīng)依賴使用日志框架SLF4J中的API,使用門面模式的日志框架,有利于維護(hù)和各個(gè)類的日志處理方式統(tǒng)一。

import org.slf4j.Logger; ?import org.slf4j.LoggerFactory; ?private static final Logger logger = LoggerFactory.getLogger(Abc.class); ?2.【強(qiáng)制】日志文件推薦至少保存15天,因?yàn)橛行┊惓>邆湟浴爸堋睘轭l次發(fā)生的特點(diǎn)。

3.【強(qiáng)制】應(yīng)用中的擴(kuò)展日志(如打點(diǎn)、臨時(shí)監(jiān)控、訪問(wèn)日志等)命名方式:

appName_logType_logName.log。logType:日志類型,推薦分類有stats/desc/monitor/visit

等;logName:日志描述。這種命名的好處:通過(guò)文件名就可知道日志文件屬于什么應(yīng)用,什么

阿里巴巴JAVA開發(fā)手冊(cè)

20 / 32

類型,什么目的,也有利于歸類查找。

正例:mppserver應(yīng)用中單獨(dú)監(jiān)控時(shí)區(qū)轉(zhuǎn)換異常,如:

mppserver_monitor_timeZoneConvert.log

說(shuō)明:推薦對(duì)日志進(jìn)行分類,錯(cuò)誤日志和業(yè)務(wù)日志盡量分開存放,便于開發(fā)人員查看,也便于

通過(guò)日志對(duì)系統(tǒng)進(jìn)行及時(shí)監(jiān)控。

4.【強(qiáng)制】對(duì)trace/debug/info級(jí)別的日志輸出,必須使用條件輸出形式或者使用占位符的方 式。

說(shuō)明:logger.debug("Processing trade with id: " + id + " symbol: " + symbol);如果

日志級(jí)別是warn,上述日志不會(huì)打印,但是會(huì)執(zhí)行字符串拼接操作,如果symbol是對(duì)象,會(huì)

執(zhí)行toString()方法,浪費(fèi)了系統(tǒng)資源,執(zhí)行了上述操作,最終日志卻沒(méi)有打印。

正例:(條件)

if (logger.isDebugEnabled()) { ???logger.debug("Processing trade with id: " + id + " symbol: " + symbol); ??}正例:(占位符)

logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol); ?5.【強(qiáng)制】避免重復(fù)打印日志,浪費(fèi)磁盤空間,務(wù)必在log4j.xml中設(shè)置additivity=false。 正例: ?6.【強(qiáng)制】異常信息應(yīng)該包括兩類信息:案發(fā)現(xiàn)場(chǎng)信息和異常堆棧信息。如果不處理,那么往上 拋。

正例:logger.error(各類參數(shù)或者對(duì)象toString + "_" + e.getMessage(), e);

7.輸出的POJO類必須重寫toString方法,否則只輸出此對(duì)象的hashCode值(地址值),沒(méi)啥 參考意義。

8.【推薦】可以使用warn日志級(jí)別來(lái)記錄用戶輸入?yún)?shù)錯(cuò)誤的情況,避免用戶投訴時(shí),無(wú)所適

從。注意日志輸出的級(jí)別,error級(jí)別只記錄系統(tǒng)邏輯出錯(cuò)、異常、或者重要的錯(cuò)誤信息。如

非必要,請(qǐng)不要在此場(chǎng)景打出error級(jí)別,避免頻繁報(bào)警。

9.【推薦】謹(jǐn)慎地記錄日志。生產(chǎn)環(huán)境禁止輸出debug日志;有選擇地輸出info日志;如果使 用warn來(lái)記錄剛上線時(shí)的業(yè)務(wù)行為信息,一定要注意日志輸出量的問(wèn)題,避免把服務(wù)器磁盤

撐爆,并記得及時(shí)刪除這些觀察日志。

說(shuō)明:大量地輸出無(wú)效日志,不利于系統(tǒng)性能提升,也不利于快速定位錯(cuò)誤點(diǎn)。紀(jì)錄日志時(shí)請(qǐng)

思考:這些日志真的有人看嗎?看到這條日志你能做什么?能不能給問(wèn)題排查帶來(lái)好處?

10.【參考】如果日志用英文描述不清楚,推薦使用中文注釋。對(duì)于中文UTF-8的日志,在secureCRT

中,set encoding=utf-8;如果中文字符還亂碼,請(qǐng)?jiān)O(shè)置:全局>默認(rèn)的會(huì)話設(shè)置>外觀>字體>

阿里巴巴JAVA開發(fā)手冊(cè)

21 / 32

選擇字符集gb2312;如果還不行,執(zhí)行命令:set termencoding=gbk,并且直接使用中文來(lái)

進(jìn)行檢索。

ts?e??&

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,441評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,475評(píng)論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,834評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,009評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,559評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,516評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,728評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,249評(píng)論 3 399
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,484評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容