LOG日志詳解

歡迎關(guān)注作者簡(jiǎn)書(shū)
csdn傳送門(mén)

LOG日志詳解

參考文檔

Log的用途

問(wèn)題追蹤:通過(guò)日志不僅僅包括我們程序的一些bug绸贡,也可以在安裝配置時(shí)排监,通過(guò)日志可以發(fā)現(xiàn)問(wèn)題。

狀態(tài)監(jiān)控:通過(guò)實(shí)時(shí)分析日志践樱,可以監(jiān)控系統(tǒng)的運(yùn)行狀態(tài)翰灾,做到早發(fā)現(xiàn)問(wèn)題缕粹、早處理問(wèn)題。

安全審計(jì):審計(jì)主要體現(xiàn)在安全上纸淮,通過(guò)對(duì)日志進(jìn)行分析平斩,可以發(fā)現(xiàn)是否存在非授權(quán)的操作。

記錄Log的基本原則

日志的級(jí)別劃分

Java日志通逞士椋可以分為:error绘面、warn、info侈沪、debug揭璃、trace五個(gè)級(jí)別。在J2SE中預(yù)定義的級(jí)別更多亭罪,分別為:SEVERE瘦馍、WARNING、INFO应役、CONFIG扣墩、FINE哲银、FINER、FINEST呻惕。

日志對(duì)性能的影響

不管是多么優(yōu)秀的日志工具荆责,在日志輸出時(shí)總會(huì)對(duì)性能產(chǎn)生或多或少的影響,為了將影響降低到最低亚脆,有以下幾個(gè)準(zhǔn)則需要遵守:

如何創(chuàng)建Logger實(shí)例:創(chuàng)建Logger實(shí)例有是否static的區(qū)別做院,在log4j的早期版本,一般要求使用static濒持,而在高版本以及后來(lái)的slf4j中键耕,該問(wèn)題已經(jīng)得到優(yōu)化,獲雀逃(創(chuàng)建)logger實(shí)例的成本已經(jīng)很低屈雄。所以我們要求:對(duì)于可以預(yù)見(jiàn)的多數(shù)情況下單例運(yùn)行的class,可以不添加static前綴官套;對(duì)于可能是多例居多酒奶,尤其是需要頻繁創(chuàng)建的class,我們要求要添加static前綴奶赔。

判斷日志級(jí)別:
n對(duì)于可以預(yù)見(jiàn)的會(huì)頻繁產(chǎn)生的日志輸出惋嚎,比如for、while循環(huán)站刑,定期執(zhí)行的job等另伍,建議先使用if對(duì)日志級(jí)別進(jìn)行判斷后再輸出。
n對(duì)于日志輸出內(nèi)容需要復(fù)雜的序列化绞旅,或輸出的某些信息獲取成本較高時(shí)摆尝,需要對(duì)日志級(jí)別進(jìn)行判斷。比如日志中需要輸出用戶名因悲,而用戶名需要在日志輸出時(shí)從數(shù)據(jù)庫(kù)獲取结榄,此時(shí)就需要先判斷一下日志級(jí)別,看看是否有必要獲取這些信息囤捻。

優(yōu)先使用參數(shù),減少字符串拼接:使用參數(shù)的方式輸出日志信息邻寿,有助于在性能和代碼簡(jiǎn)潔之間取得平衡蝎土。當(dāng)日志級(jí)別限制輸出該日志時(shí),參數(shù)內(nèi)容將不會(huì)融合到最終輸出中绣否,減少了字符串的拼接誊涯,從而提升執(zhí)行效率。

什么時(shí)候輸出日志

日志并不是越多越詳細(xì)就越好蒜撮。在分析運(yùn)行日志暴构,查找問(wèn)題時(shí)跪呈,我們經(jīng)常遇到該出現(xiàn)的日志沒(méi)有,無(wú)用的日志一大堆取逾,或者有效的日志被大量無(wú)意義的日志信息淹沒(méi)耗绿,查找起來(lái)非常困難。那么什么時(shí)候輸出日志呢砾隅?以下列出了一些常見(jiàn)的需要輸出日志的情況误阻,而且日志的級(jí)別基本都是>=INFO,至于Debug級(jí)別日志的使用場(chǎng)景晴埂,本節(jié)沒(méi)有專門(mén)列出究反,需要具體情況具體分析,但也是要追求“恰如其分”儒洛,不是越多越好精耐。

系統(tǒng)啟動(dòng)參數(shù)、環(huán)境變量

系統(tǒng)啟動(dòng)的參數(shù)琅锻、配置卦停、環(huán)境變量、System.Properties等信息對(duì)于軟件的正常運(yùn)行至關(guān)重要浅浮,這些信息的輸出有助于安裝配置人員通過(guò)日志快速定位問(wèn)題沫浆,所以程序有必要在啟動(dòng)過(guò)程中把使用到的關(guān)鍵參數(shù)、變量在日志中輸出出來(lái)滚秩。在輸出時(shí)需要注意专执,不是一股腦的全部輸出,而是將軟件運(yùn)行涉及到的配置信息輸出出來(lái)郁油。比如本股,如果軟件對(duì)jvm的內(nèi)存參數(shù)比較敏感,對(duì)最低配置有要求桐腌,那么就需要在日志中將-Xms -Xmx -XX:PermSize這幾個(gè)參數(shù)的值輸出出來(lái)拄显。

異常捕獲處

在捕獲異常處輸出日志,大家在基本都能做到案站,唯一需要注意的是怎么輸出一個(gè)簡(jiǎn)單明了的日志信息躬审。這在后面的問(wèn)題問(wèn)題中有進(jìn)一步說(shuō)明。

函數(shù)獲得期望之外的結(jié)果時(shí)

一個(gè)函數(shù)蟆盐,尤其是供外部系統(tǒng)或遠(yuǎn)程調(diào)用的函數(shù)承边,通常都會(huì)有一個(gè)期望的結(jié)果,但如果內(nèi)部系統(tǒng)或輸出參數(shù)發(fā)生錯(cuò)誤時(shí)石挂,函數(shù)將無(wú)法返回期望的正確結(jié)果博助,此時(shí)就需要記錄日志,日志的基本通常是warn痹愚。需要特別說(shuō)明的是富岳,這里的期望之外的結(jié)果不是說(shuō)沒(méi)有返回就不需要記錄日志了蛔糯,也不是說(shuō)返回false就需要記錄日志。比如函數(shù):isXXXXX()窖式,無(wú)論返回true蚁飒、false記錄日志都不是必須的,但是如果系統(tǒng)內(nèi)部無(wú)法判斷應(yīng)該返回true還是false時(shí)脖镀,就需要記錄日志飒箭,并且日志的級(jí)別應(yīng)該至少是warn。

關(guān)鍵操作

關(guān)鍵操作的日志一般是INFO級(jí)別蜒灰,如果數(shù)量弦蹂、頻度很高,可以考慮使用DEBUG級(jí)別强窖。以下是一些關(guān)鍵操作的舉例凸椿,實(shí)際的關(guān)鍵操作肯定不止這么多。

刪除:刪除一個(gè)文件翅溺、刪除一組重要數(shù)據(jù)庫(kù)記錄……

添加:和外系統(tǒng)交互時(shí)脑漫,收到了一個(gè)文件、收到了一個(gè)任務(wù)……

處理:開(kāi)始咙崎、結(jié)束一條任務(wù)……

……

日志輸出的內(nèi)容

ERROR:錯(cuò)誤的簡(jiǎn)短描述优幸,和該錯(cuò)誤相關(guān)的關(guān)鍵參數(shù),如果有異常褪猛,要有該異常的StackTrace网杆。

WARN:告警的簡(jiǎn)短描述,和該錯(cuò)誤相關(guān)的關(guān)鍵參數(shù)伊滋,如果有異常碳却,要有該異常的StackTrace。

INFO:言簡(jiǎn)意賅地信息描述笑旺,如果有相關(guān)動(dòng)態(tài)關(guān)鍵數(shù)據(jù)昼浦,要一并輸出,比如相關(guān)ID筒主、名稱等关噪。

DEBUG:簡(jiǎn)單描述,相關(guān)數(shù)據(jù)乌妙,如果有異常使兔,要有該異常的StackTrace。

在日志相關(guān)數(shù)據(jù)輸出的時(shí)要特別注意對(duì)敏感信息的保護(hù)冠胯,比如修改密碼時(shí),不能將密碼輸出到日志中锦针。

什么時(shí)候使用J2SE自帶的日志

我們通常使用slf4j或log4j這兩個(gè)工具記錄日志荠察,那么還需要使用J2SE的日志框架嗎置蜀?當(dāng)然需要,在我們編寫(xiě)一些通用的工具類時(shí)悉盆,為了減少對(duì)第三方的jar包的依賴盯荤,首先要考慮使用java.util.logging。

考慮到slf4j等日志框架提供了日志bridge工具焕盟,為java.util.logging提供了Handler秋秤,所以普通應(yīng)用的開(kāi)發(fā)過(guò)程中也可以考慮使用J2SE自有日志,這樣不但可以減少項(xiàng)目的編譯依賴脚翘,同時(shí)在應(yīng)用實(shí)施時(shí)可以更靈活的選擇日志的輸出工具包灼卢。

典型問(wèn)題分析

該用日志的地方不用

上圖對(duì)異常的處理直接使用e.printStackTrace()顯然是有問(wèn)題的,正確的做法是:要么通過(guò)日志方式輸出錯(cuò)誤信息来农,要么直接拋出異常鞋真,要么創(chuàng)建新的自定義異常拋出。

另:對(duì)于靜態(tài)工具類函數(shù)中的異常處理沃于,最簡(jiǎn)單的方式就是不捕獲涩咖、不記錄日志,直接向上拋出繁莹,如果認(rèn)為異常類型太多檩互,或者意義不明確,可以拋出自定義異常類的實(shí)例咨演。

啰嗦重復(fù)闸昨、沒(méi)有重點(diǎn)

首先上面不應(yīng)該有error級(jí)別的日志。

其次在日志中直接輸出e.toString()雪标,為定位問(wèn)題提供的信息太少零院。

另外需要明確一點(diǎn):日志系統(tǒng)是一個(gè)多線程公用的系統(tǒng),在兩行日志輸出之間有可能會(huì)被插入其他線程的日志記錄村刨,不會(huì)按照我們的意愿順序輸出告抄,后面有更典型的例子。

最后嵌牺,上面的日志可以簡(jiǎn)化為:

logger.debug(“從properties中...{}...{}...”,name, value, e); logger.warn(“從properties中獲取{}發(fā)生錯(cuò)誤:{}”,name, e.toString());

或者直接一句:

logger.warn(“從properties中...{}...{}...”,name, value, e);

或者更完美的:

if(logger.isDebugEnabled()){ logger.warn(“從properties中...{}...”, name, e); }else{ logger.warn(“從properties中獲取{}發(fā)生錯(cuò)誤:{}”, name, e.toString()); }

日志和異常處理的關(guān)系

首先上面的日志信息不夠充分打洼,級(jí)別定義不夠恰當(dāng)。

另外逆粹,既然將異常捕獲并記錄的日志募疮,就不應(yīng)該重新將一個(gè)一模一樣的異常再次拋出去了。如果將異常再次拋出僻弹,那在上層肯定還需要對(duì)該異常進(jìn)行處理阿浓,并記錄日志,這樣就重復(fù)了蹋绽。如果沒(méi)有特別原因芭毙,此處不應(yīng)該捕獲異常筋蓖。

System.out方式的日志

上面的日志形式十分隨意,只適合臨時(shí)的代碼調(diào)試退敦,不允許提交到正式的代碼庫(kù)中粘咖。

對(duì)于臨時(shí)調(diào)試日志,建議在日志的輸出信息中添加一些特殊的連續(xù)字符侈百,也可以用自己的名稱瓮下、代號(hào),這樣可以在調(diào)試完畢后钝域,提交代碼之前讽坏,方便地找到所有臨時(shí)代碼,一并刪除网梢。

日志信息不明確

上面的“添加任務(wù)出錯(cuò)震缭。。战虏〖鹪祝”既沒(méi)有記錄任務(wù)id,也沒(méi)有任務(wù)名稱烦感,軟件部署后發(fā)現(xiàn)錯(cuò)誤后巡社,根據(jù)該日志記錄不能確認(rèn)哪一條任務(wù)錯(cuò)誤,給進(jìn)一步的分析原因帶來(lái)困難手趣。

另外第二個(gè)紅圈中的問(wèn)題有:要使用參數(shù)晌该;一行日志就可以了。

還有一些其他共性的錯(cuò)誤绿渣,就不多說(shuō)了朝群。

忘記日志輸出是多線程公用的

如果有另外一個(gè)線程正在輸出日志,上面的記錄就會(huì)被打斷中符,最終顯示輸出和預(yù)想的就會(huì)不一致姜胖。正確的做法應(yīng)是將這些信息放到一行,如果需要換行可以考慮使用“\r”淀散,如果內(nèi)容較多右莱,考慮增加if (logger.isDebugEnabled())進(jìn)行判斷。而第二個(gè)例子中的輸出有System.out的習(xí)慣档插,相關(guān)內(nèi)容應(yīng)該一行完成慢蜓。

多個(gè)參數(shù)的處理

對(duì)于多參的日志輸出,可以考慮:

public void debug(String format, Object... arguments);

但是在使用多參時(shí)郭膛,會(huì)創(chuàng)建一個(gè)對(duì)象數(shù)組晨抡,也會(huì)有一定的消耗,為此,在對(duì)性能敏感的場(chǎng)景耘柱,可以增加對(duì)日志級(jí)別的判斷圆雁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市帆谍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌轴咱,老刑警劉巖汛蝙,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異朴肺,居然都是意外死亡窖剑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)戈稿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)西土,“玉大人,你說(shuō)我怎么就攤上這事鞍盗⌒枇耍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵般甲,是天一觀的道長(zhǎng)肋乍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)敷存,這世上最難降的妖魔是什么墓造? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮锚烦,結(jié)果婚禮上觅闽,老公的妹妹穿的比我還像新娘。我一直安慰自己涮俄,他們只是感情好蛉拙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著禽拔,像睡著了一般刘离。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上睹栖,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天硫惕,我揣著相機(jī)與錄音,去河邊找鬼野来。 笑死恼除,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播豁辉,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼令野,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了徽级?” 一聲冷哼從身側(cè)響起气破,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎餐抢,沒(méi)想到半個(gè)月后现使,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旷痕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年碳锈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欺抗。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡售碳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绞呈,到底是詐尸還是另有隱情贸人,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布佃声,位于F島的核電站灸姊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏秉溉。R本人自食惡果不足惜力惯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望召嘶。 院中可真熱鬧父晶,春花似錦、人聲如沸弄跌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)铛只。三九已至埠胖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淳玩,已是汗流浹背直撤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜕着,地道東北人谋竖。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓红柱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蓖乘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锤悄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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

  • idea 添加注釋/** 然后回車 選中代碼塊 Ctrl+Shift+/ 重點(diǎn)推薦閱讀:https://www....
    Helen_Cat閱讀 19,891評(píng)論 0 37
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說(shuō)明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常嘉抒。 O...
    我想起個(gè)好名字閱讀 5,317評(píng)論 0 9
  • 原文:https://zhuanlan.zhihu.com/p/27363484?hmsr=toutiao.io&...
    No_21312閱讀 1,147評(píng)論 0 12
  • 程序員的日常離不開(kāi)日志零聚,日志就好比私人秘書(shū),負(fù)責(zé)運(yùn)行周期一切trace工作些侍。優(yōu)秀的日志實(shí)踐能極大幫助地程序員快速定...
    Java架構(gòu)閱讀 822評(píng)論 0 3
  • 本文翻譯自logging howto 基礎(chǔ)教程 日志是跟蹤軟件運(yùn)行時(shí)發(fā)生事件的一種手段握牧。Python開(kāi)發(fā)者在代碼中...
    大蟒傳奇閱讀 4,254評(píng)論 0 17