一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

一個(gè)著名的日志系統(tǒng)是怎么設(shè)計(jì)出來的?

 alayavijnana 2017-10-23
1
前言

Java帝國在誕生之初就提供了集合、線程、IO、網(wǎng)絡(luò)等常用功能,從C和C++領(lǐng)地那里吸引了大量程序員過來加盟,但是卻有意無意地忽略了一個(gè)重要的功能: 輸出日志。


對于這一點(diǎn),IO大臣其實(shí)非常清楚, 日志是個(gè)很重要的東西, 因?yàn)槌绦蜻\(yùn)行起來以后, 基本上就是一個(gè)黑盒子,如果程序的行為和預(yù)料的不一致,那就是出現(xiàn)Bug了,如何去定位這個(gè)Bug 呢?   


臣民們能用的工具有兩個(gè),第一個(gè)就是單步調(diào)試,一步步地跟蹤,查看代碼中變量的值, 這種辦法費(fèi)時(shí)費(fèi)力, 并且只能在程序員的機(jī)器上才能用。 


第二種就是在特定的地方打印日志, 通過日志的輸出,幫助快速定位。尤其是當(dāng)代碼在生產(chǎn)環(huán)境上跑起來以后, 日志信息更是必不可少,要不然出了狀況兩眼一抹黑,上哪兒找問題去? 總不能讓臣民們把自己變成一個(gè)線程進(jìn)入系統(tǒng)來執(zhí)行吧?


但是IO大臣也有自己的小算盤: 日志嘛, 用我的System.out.println(.....) 不就可以了?!   我還提供了System.err.println不是?  


在IO大臣的阻撓下, 從帝國的第一代國王到第三代國王, 都沒有在JDK中提供日志相關(guān)的工具包, 臣民們只好忍受著去使用System.out.println去輸出日志,把所有的信息都輸出到控制臺, 讓那里變成一堆垃圾。


2
張家村

 張家村的電子商務(wù)系統(tǒng)也不能幸免,自然也遇到了日志的問題。經(jīng)驗(yàn)豐富的老村長已經(jīng)煩透了System.out.println所輸出的大量難于理解的無用信息,看著村民民整天苦逼地和這些System.out做斗爭,他找來了小張,命令他設(shè)計(jì)一個(gè)通用的處理日志的系統(tǒng)。


小張?jiān)谙㈥?duì)列和JMS的設(shè)計(jì)上花了不少功夫, 積累了豐富的經(jīng)驗(yàn),從那以后一直都是實(shí)現(xiàn)業(yè)務(wù)代碼,一直都是CRUD, 張二妮整天笑話自己是HTML填空人員,這一回一定要讓她看看自己的設(shè)計(jì)功力!


(傳送門:《Java帝國之消息隊(duì)列》,《Java帝國之JMS的誕生》)


老村長給小張下達(dá)的需求是這樣的:


1.  日志消息除了能打印到控制臺, 還可以輸出到文件,甚至可以通過郵件發(fā)送出去(例如生成環(huán)境出錯(cuò)的消息)


2. 日志內(nèi)容應(yīng)該可以做格式化, 例如變成純文本,XML, HTML格式等等


3. 對于不同的Java class,不同的 package , 還有不同級別的日志,應(yīng)該可以靈活地輸出到不同的文件中。

例如對于com.foo 這個(gè)package,所有的日志都輸出到 foo.log 文件中

對于com.bar 這個(gè)package ,所有文件都輸出到bar. log文件中

對于所有的ERROR級別的日志,都輸出到  errors.log文件中


4. 能對日志進(jìn)行分級, 有些日志純屬debug , 在本機(jī)或者測試環(huán)境使用, 方便程序員的調(diào)試, 生產(chǎn)環(huán)境完全不需要。有些日志是描述錯(cuò)誤(error)的, 在生產(chǎn)環(huán)境下出錯(cuò)的話必須要記錄下來,幫助后續(xù)的分析。


小張仔細(xì)看了看,拍著胸脯對老村長說:“沒問題, 明天一定讓您老看到結(jié)果?!?/span>


3
小張的設(shè)計(jì)

老村長走了以后,小張開始分析需求, 祭出“面向?qū)ο笤O(shè)計(jì)大法”,試圖從村長的需求中抽象出一點(diǎn)概念。


首先要記錄日志,肯定需要一個(gè)類來表達(dá)日志的概念,這個(gè)類至少應(yīng)該有兩個(gè)屬性,一個(gè)是時(shí)間戳,一個(gè)是消息本身,把它叫做LoggingEvent吧,記錄日志就像記錄一個(gè)事件嘛。


其次是日志可以輸出到不同的地方,控制臺、文件、郵件等等, 這個(gè)可以抽象一下,不就是寫到不同的目的地嗎? 可以叫做LogDestination? 


嗯, 還是簡單一點(diǎn),叫做Appender吧, 暗含了可以不斷追加日志的意思。



至于第二條的日志內(nèi)容可以格式化,完全可以比葫蘆畫瓢, 定義一個(gè)Formatter接口去格式化消息。



對了, Appender 應(yīng)該引用Formatter ,這樣以來就可以對LoggingEvent記錄格式化以后再發(fā)送。 


第三條需求把小張給難住了,不同的class, package 輸出的目的地不同?  “目的地”這個(gè)概念是由Appender來表達(dá)的, 難道讓不同的class, package 和Appender關(guān)聯(lián)? 不不, 不能這樣 ! 


還需要一個(gè)新的概念 , 這個(gè)概念是什么? 


從用戶角度想一下, 村民們要想獲取日志,必須得先獲取個(gè)什么東西,這個(gè)東西是不是可以稱為Logger?。?nbsp; 靈感的火花就閃了那么一下就被小張抓住了: 獲取Logger的時(shí)候要傳入類名或者包名! 



這樣一來,不同的class, package就區(qū)分開了, 然后讓Logger 和Appender關(guān)聯(lián),靈活地設(shè)置日志的目的地, 并且一個(gè)Logger可以擁有多個(gè)Appender,同一條日志消息可以輸出到多個(gè)地方, 完美!



小張迅速地畫出了核心類的類圖:



還算漂亮,小張?zhí)兆碇晕倚蕾p了一下。 


再接再厲, 把第四條需求也設(shè)計(jì)一下,日志要分級,這個(gè)簡單, 定義一個(gè)Priority的類,里邊定義5個(gè)常量DEBUG, INFO, WARN, ERROR, FATAL, 表示5個(gè)不同的級別就OK了。當(dāng)然這我5個(gè)級別有高低之分, DEBUG級別最低, FATAL級別最高。


還可以給Logger增加一些輔助編程的方法,如Logger.debug(....) , Logger.info(...)  , Logger.warn(...) 等等, 這樣村民們將來就可以輕松地輸出各種級別的日志了。


等一下, 老村長還說過“對于所有的ERROR級別的日志,都輸出到  errors.log文件中” 類似這樣的需求, 好像給忽略了。


這也好辦嘛, 只要在Appender上增加一個(gè)屬性,就叫做Priority, 如果用戶要輸出的日志是DEBUG級別, 但是有個(gè)FileAppender的Priority是 ERROR級別,那這個(gè)日志就不用在這個(gè)FileAppender中輸出了 ,因?yàn)镋RROR級別比DEBUG級別高嘛。


同理, 在Logger類上也可以增加一個(gè)Priority的屬性,用戶可以去設(shè)置, 如果一個(gè)Logger的Priority是ERROR, 而用戶調(diào)用了這個(gè)Logger的debug方法, 那這個(gè)debug 的消息也不會輸出。


小張全心全意地投入到設(shè)計(jì)當(dāng)中,一看時(shí)間, 都快半夜了, 趕緊休息, 明天向村長匯報(bào)去。 


4
正交性

第二天, 小張給老村長展示了自己設(shè)計(jì)的LoggerEvent, Logger , Appender, Formatter, Priority 等類和接口, 老村長捻著胡子滿意地點(diǎn)點(diǎn)頭:“不錯(cuò)不錯(cuò),與上一次相比有巨大的進(jìn)步。你知不知道我在需求中其實(shí)給了你引導(dǎo)?”


“引導(dǎo)? 什么引導(dǎo)? ”


“就是讓你朝著正交的方向去努力啊”


“正交? ”


‘“如果你把Logger, Appender, Formatter看成坐標(biāo)系中的X軸,Y軸,Z軸, 你看看,這三者是不是可以獨(dú)立變化而不互相影響???”



“我賽,果然如此,我可以任意擴(kuò)展Appender接口而影響不到Logger和Formatter, 無論有多少個(gè)Logger 都影響不了Appender和Formatter , 這就是正交了?”


“是啊,當(dāng)你從系統(tǒng)中提取出正交的概念的時(shí)候,那就威力無比了,因?yàn)樽兓环庋b在了一個(gè)維度上,你可以把這些概念任意組合,而不會變成意大利面條似的代碼。 ”


聽到村長做了理論的升華, 小張興奮得直搓手。 


“好吧,你把這個(gè)設(shè)計(jì)實(shí)現(xiàn)了吧,對了,你打算叫什么名字? ”  村長問道


“我打算把他叫做Log4j , 意思是Log for Java”


“不錯(cuò),就這么定了吧”


5
Log4j

小張又花了兩個(gè)月的時(shí)間把Log4j 開發(fā)了出來, 由于Log4j有著良好的設(shè)計(jì),優(yōu)異的性能, 不僅僅是張家村的人在用, Java帝國的很多村鎮(zhèn)、部落都愛上了它。


后來張家村把Log4j 在Apache部落開源了, 這下子吸引了無數(shù)的人無償幫助測試它,擴(kuò)展它,改進(jìn)它, 很快就成了帝國最流行的日志工具。


張家村建議帝國把Log4j 納入到JDK 中, 帝國那效率低下的官僚機(jī)構(gòu)竟然拒絕了。  消息傳到了IO大臣的耳朵里,他不由的扼腕嘆息: 唉,失去了一次極好的招安機(jī)會啊。 現(xiàn)在唯一的辦法就是趕緊上奏皇上,在官方也提供一套,爭取讓臣民們使用官方版本。


到了第四代國王(JDK1.4),臣民們終于看到了帝國提供的java.util.logging包,也是用來記錄日志的,并且其中的核心概念Logger, Formatter, Handler 和 Log4j非常相似,只是為時(shí)已晚, Log4j早已深入人心了, 不可撼動(dòng)了。  


6
尾聲

Log4j 在Apache開源以后, 小張也逐漸地有點(diǎn)落寞,他閑不住又寫了一個(gè)工具,叫做logback, 有了之前的經(jīng)驗(yàn),這logback 比log4j 還要快。 


如今的日志世界有了很多的選擇 ,除了java.util.logging, log4j 之外,還有l(wèi)ogback,tinylog 等其他工具。


小張想了想, 這么多日志工具,用戶如果想切換了怎么辦?不想用log4j了,能換到logback嗎? 


我還是提供一個(gè)抽象層吧, 用戶用這個(gè)抽象層的API來寫日志, 底層具體用什么日志工具不用關(guān)心,這樣就可以移植了。 


小張把這抽象層就叫做Simple Logging Facade for Java,簡稱SLF4J。  



對于Log4j , JDK logging, tinylog 等工具, 需要一個(gè)適配層, 把SLF4J 的API轉(zhuǎn)化成具體工具的調(diào)用接口。 


由于Logback這個(gè)工具也是出自小張之手, 直接實(shí)現(xiàn)了SLF4J的API,所以連適配層都不需要了, 用起來速度飛快,效率最高,SLFJ4+Logback 成為了很多人的最愛, 大有超越Apache Common Logging + Log4j 之勢。 


后記: 本文主要想講一下日志工具的歷史和現(xiàn)狀, 尤其是Log4j核心的設(shè)計(jì)理念。


文中的小張其實(shí)就是Ceki Gülcü,他開發(fā)了Log4j , logback,以及slfj4, 為Java的日志事業(yè)做出了卓越的貢獻(xiàn)。

(完)


    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲视频一级二级三级| 久久精品国产亚洲熟女| 亚洲精品国男人在线视频| 香港国产三级久久精品三级| 好吊色欧美一区二区三区顽频| 91精品日本在线视频| 91人妻人人揉人人澡人| 色偷偷亚洲女人天堂观看| 在线视频三区日本精品| 日韩成人动画在线观看| 国产又粗又硬又长又爽的剧情| 人妻露脸一区二区三区| 午夜视频免费观看成人| 九九热精彩视频在线播放| 亚洲国产精品久久琪琪| 亚洲国产黄色精品在线观看| 69精品一区二区蜜桃视频 | 亚洲一区二区精品国产av| 日本午夜免费观看视频| 亚洲男女性生活免费视频| 欧美精品中文字幕亚洲| 欧美熟妇喷浆一区二区| 夫妻性生活一级黄色录像| 中文字幕日韩欧美一区| 亚洲国产丝袜一区二区三区四| 日本午夜免费福利视频| 黄色国产自拍在线观看| 91后入中出内射在线| 久久精品国产99精品最新| 国产a天堂一区二区专区| 成人三级视频在线观看不卡| 久草视频这里只是精品| 国产日韩中文视频一区| 日韩中文字幕欧美亚洲| 1024你懂的在线视频| 夫妻激情视频一区二区三区 | 夫妻性生活真人动作视频| 久久综合亚洲精品蜜桃| 又大又长又粗又黄国产| 久久久精品日韩欧美丰满| 伊人久久青草地综合婷婷|