java Log規(guī)范

Overview

一個(gè)在生產(chǎn)環(huán)境里運(yùn)行的程序如果沒(méi)有日志是很讓維護(hù)者提心吊膽的,有太多雜亂又無(wú)意義的日志也是令人傷神环鲤。程序出現(xiàn)問(wèn)題時(shí)候,從日志里如果發(fā)現(xiàn)不了問(wèn)題可能的原因是很令人受挫的。本文想討論的是如何在Java程序里寫(xiě)好日志季蚂。

一般來(lái)說(shuō)日志分為兩種:業(yè)務(wù)日志和異常日志,使用日志我們希望能達(dá)到以下目標(biāo):

  1. 對(duì)程序運(yùn)行情況的記錄和監(jiān)控琅束;
  2. 在必要時(shí)可詳細(xì)了解程序內(nèi)部的運(yùn)行狀態(tài)扭屁;
  3. 對(duì)系統(tǒng)性能的影響盡量小涩禀;

Java日志框架

  1. Log4j 或 Log4j 2 Apache的開(kāi)源項(xiàng)目料滥,通過(guò)使用Log4j,我們可以控制日志信息輸送的目的地是控制臺(tái)艾船、文件葵腹、GUI組件、甚至是套接口服務(wù)器屿岂、NT的事件記錄器践宴、UNIX Syslog守護(hù)進(jìn)程等;用戶也可以控制每一條日志的輸出格式爷怀;通過(guò)定義每一條日志信息的級(jí)別阻肩,用戶能夠更加細(xì)致地控制日志的生成過(guò)程。這些可以通過(guò)一個(gè)配置文件(XML或Properties文件)來(lái)靈活地進(jìn)行配置运授,而不需要修改程序代碼烤惊。Log4j 2則是前任的一個(gè)升級(jí)乔煞,參考了Logback的許多特性;

  2. Logback - Logback是由log4j創(chuàng)始人設(shè)計(jì)的又一個(gè)開(kāi)源日記組件撕氧。logback當(dāng)前分成三個(gè)模塊:logback-core,logback- classic和logback-access瘤缩。logback-core是其它兩個(gè)模塊的基礎(chǔ)模塊。logback-classic是log4j的一個(gè)改良版本伦泥。此外logback-classic完整實(shí)現(xiàn)SLF4J API使你可以很方便地更換成其它日記系統(tǒng)如log4j或JDK14 Logging剥啤;

  3. java.util.logging - JDK內(nèi)置的日志接口和實(shí)現(xiàn),功能比較簡(jiǎn)不脯;

  4. Slf4j - SLF4J是為各種Logging API提供一個(gè)簡(jiǎn)單統(tǒng)一的接口府怯,從而使用戶能夠在部署的時(shí)候配置自己希望的Logging API實(shí)現(xiàn);

  5. Apache Commons Logging - Apache Commons Logging (JCL)希望解決的問(wèn)題和Slf4j類(lèi)似防楷。

選項(xiàng)太多了的后果就是選擇困難癥牺丙,我的看法是沒(méi)有最好的,只有最合適的复局。在比較關(guān)注性能的地方冲簿,選擇Logback或自己實(shí)現(xiàn)高性能Logging API可能更合適;在已經(jīng)使用了Log4j的項(xiàng)目中亿昏,如果沒(méi)有發(fā)現(xiàn)問(wèn)題峦剔,繼續(xù)使用可能是更合適的方式;我一般會(huì)在項(xiàng)目里選擇使用Slf4j, 如果不想有依賴(lài)則使用java.util.logging或框架容器已經(jīng)提供的日志接口角钩。

Java日志最佳實(shí)踐

定義日志變量

日志變量往往不變吝沫,最好定義成final static,變量名用大寫(xiě)递礼。

日志分級(jí)

Java的日志框架一般會(huì)提供以下日志級(jí)別惨险,缺省打開(kāi)info級(jí)別,也就是debug脊髓,trace級(jí)別的日志在生產(chǎn)環(huán)境不會(huì)輸出辫愉,在開(kāi)發(fā)和測(cè)試環(huán)境可以通過(guò)不同的日志配置文件打開(kāi)debug級(jí)別。

  1. fatal - 嚴(yán)重的将硝,造成服務(wù)中斷的錯(cuò)誤
  2. error - 其他錯(cuò)誤運(yùn)行期錯(cuò)誤
  3. warn - 警告信息恭朗,如程序調(diào)用了一個(gè)即將作廢的接口,接口的不當(dāng)使用袋哼,運(yùn)行狀態(tài)不是期望的但仍可繼續(xù)處理等
  4. info - 有意義的事件信息冀墨,如程序啟動(dòng)闸衫,關(guān)閉事件涛贯,收到請(qǐng)求事件等
  5. debug - 調(diào)試信息,可記錄詳細(xì)的業(yè)務(wù)處理到哪一步了蔚出,以及當(dāng)前的變量狀態(tài)
  6. trace - 更詳細(xì)的跟蹤信息

基本的Logger編碼規(guī)范

  1. 在一個(gè)對(duì)象中通常只使用一個(gè)Logger對(duì)象弟翘,Logger應(yīng)該是static final的虫腋,只有在少數(shù)需要在構(gòu)造函數(shù)中傳遞logger的情況下才使用private final。

    
    private static final Logger LOGGER=LoggerFactory.getLogger(Main.class);
        
    
  2. 輸出Exceptions的全部Throwable信息稀余,因?yàn)閘ogger.error(msg)和logger.error(msg,e.getMessage())這樣的日志輸出方法會(huì)丟失掉最重要的StackTrace信息悦冀。

    LOGGER.error("error", e.getMessage()); //錯(cuò)誤
        
    LOGGER.error(e.getMessage()); //錯(cuò)誤
        
    LOGGER.error(e.getMessage(), e);  //正確
        
    LOGGER.error(e);     //正確
        
    
  3. 不允許記錄日志后又拋出異常,因?yàn)檫@樣會(huì)多次記錄日志睛琳,只允許記錄一次日志盒蟆。

    try{
        // do something
    }catch(Exception e){
        LOGGER.error(e.getMessage(), e);
        throw new Exception("error");
    }
    
  4. 不允許出現(xiàn)System print(包括System.out.println和System.error.println)語(yǔ)句。

    try{
        // do something
    }catch(Exception e){
        System.out.println(e.getMessage());
        System.error.println(e.getMessage());
    }
    
  5. 不允許出現(xiàn)printStackTrace师骗。

    try{
        // do something
    }catch(Exception e){
        e. printStackTrace();
    }
    
  6. 日志性能的考慮历等,如果代碼為核心代碼,執(zhí)行頻率非常高辟癌,則輸出日志建議增加判斷寒屯,尤其是低級(jí)別的輸出<debug、info黍少、warn>寡夹。

    debug日志太多后可能會(huì)影響性能,有一種改進(jìn)方法是:

    if(LOGGER.isDebugEnable()){
        LOGGER.debug("do something");
    }
    

    但更好的方法是Slf4j提供的最佳實(shí)踐:

    LOGGER.debug("do something {}", content);
    

    一方面可以減少參數(shù)構(gòu)造的開(kāi)銷(xiāo)厂置,另一方面也不用多寫(xiě)兩行代碼菩掏。

  7. 有意義的日志

    通常情況下在程序日志里記錄一些比較有意義的狀態(tài)數(shù)據(jù):程序啟動(dòng),退出的時(shí)間點(diǎn)农渊;程序運(yùn)行消耗時(shí)間患蹂;耗時(shí)程序的執(zhí)行進(jìn)度;重要變量的狀態(tài)變化砸紊。

    初次之外传于,在公共的日志里規(guī)避打印程序的調(diào)試或者提示信息。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末醉顽,一起剝皮案震驚了整個(gè)濱河市沼溜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌游添,老刑警劉巖系草,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異唆涝,居然都是意外死亡找都,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén)廊酣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)能耻,“玉大人,你說(shuō)我怎么就攤上這事∠停” “怎么了饿幅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)戒职。 經(jīng)常有香客問(wèn)我栗恩,道長(zhǎng),這世上最難降的妖魔是什么洪燥? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任磕秤,我火速辦了婚禮,結(jié)果婚禮上捧韵,老公的妹妹穿的比我還像新娘亲澡。我一直安慰自己,他們只是感情好纫版,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布床绪。 她就那樣靜靜地躺著,像睡著了一般其弊。 火紅的嫁衣襯著肌膚如雪癞己。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天梭伐,我揣著相機(jī)與錄音痹雅,去河邊找鬼。 笑死糊识,一個(gè)胖子當(dāng)著我的面吹牛绩社,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赂苗,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼愉耙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了拌滋?” 一聲冷哼從身側(cè)響起朴沿,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎败砂,沒(méi)想到半個(gè)月后赌渣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昌犹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年坚芜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斜姥。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鸿竖,死狀恐怖路操,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情千贯,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布搞坝,位于F島的核電站搔谴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏桩撮。R本人自食惡果不足惜敦第,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望店量。 院中可真熱鬧芜果,春花似錦、人聲如沸融师。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)旱爆。三九已至舀射,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間怀伦,已是汗流浹背脆烟。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留房待,地道東北人邢羔。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像桑孩,于是被迫代替她去往敵國(guó)和親拜鹤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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

  • 在應(yīng)用程序中添加日志記錄總的來(lái)說(shuō)基于三個(gè)目的:監(jiān)視代碼中變量的變化情況流椒,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計(jì)分析...
    時(shí)待吾閱讀 4,975評(píng)論 0 6
  • 在應(yīng)用程序中添加日志記錄總的來(lái)說(shuō)基于三個(gè)目的:監(jiān)視代碼中變量的變化情況署惯,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計(jì)分析...
    時(shí)待吾閱讀 4,981評(píng)論 1 13
  • 寫(xiě)Java也有一段時(shí)間了,一直都有用slf4j log4j輸出日志的習(xí)慣镣隶。但是始終都是抱著“拿來(lái)主義”的態(tài)度极谊,復(fù)制...
    Minimumy閱讀 1,380評(píng)論 1 7
  • 概述 在項(xiàng)目開(kāi)發(fā)中,為了跟蹤代碼的運(yùn)行情況安岂,常常要使用日志來(lái)記錄信息轻猖。在Java世界,有很多的日志工具庫(kù)來(lái)實(shí)現(xiàn)日志...
    靜默虛空閱讀 1,842評(píng)論 1 9
  • 前言 最近學(xué)習(xí)開(kāi)java web服務(wù)器開(kāi)發(fā)域那,開(kāi)始學(xué)習(xí)java咙边,處理業(yè)務(wù)邏輯猜煮,但對(duì)其中的日志比較好奇,之前沒(méi)怎么接觸...
    九風(fēng)萍舟閱讀 3,286評(píng)論 1 6