日志框架 - 基于spring-boot - 設(shè)計(jì)

日志框架系列講解文章
日志框架 - 基于spring-boot - 使用入門
日志框架 - 基于spring-boot - 設(shè)計(jì)
日志框架 - 基于spring-boot - 實(shí)現(xiàn)1 - 配置文件
日志框架 - 基于spring-boot - 實(shí)現(xiàn)2 - 消息定義及消息日志打印
日志框架 - 基于spring-boot - 實(shí)現(xiàn)3 - 關(guān)鍵字與三種消息解析器
日志框架 - 基于spring-boot - 實(shí)現(xiàn)4 - HTTP請求攔截
日志框架 - 基于spring-boot - 實(shí)現(xiàn)5 - 線程切換
日志框架 - 基于spring-boot - 實(shí)現(xiàn)6 - 自動裝配

在前文 日志框架 - 基于spring-boot - 使用入門 中,我介紹了日志框架的使用。

但讀者看到了可能云里霧里的,因?yàn)闆]有代碼也沒有設(shè)計(jì)說明。所以你猜的沒錯!這一次就要來向各位觀眾揭示這小玩意里面的道道。

源起混亂的日志代碼

前文已經(jīng)解釋過為什么要新造一個日志框架。
但我想靠文字不能有深切的體會。
下面是我在讀別人代碼時經(jīng)??吹降拇a:

logger.info("#{}#{}#{}#{}#{}", new String[]{
             orderInfo.getOrderNo() /*訂單號*/, 
             orderInfo.getTradeCode() /*交易代碼*/, 
             orderInfo.getReqSys() /*請求方系統(tǒng)*/, 
             orderInfo.getLocale() /*區(qū)域代碼*/, 
             "req done" /*日志內(nèi)容*/})

沒有粗暴的用字符串相加,說明開發(fā)人員已經(jīng)有一點(diǎn)水平了,但是……

這段代碼意味著多糟糕的事情呢?。?/strong>
寫上面這段代碼的可能是某個加班熬夜到神志模糊的程序員,更糟的是他借差迷糊勁把其中的兩行寫反了!
不對照著日志規(guī)范細(xì)扣,基本沒有人能發(fā)現(xiàn)問題。

為了讓W(xué)EB層的Controller與業(yè)務(wù)層的Service都能這樣打印,Service層接口硬生生插入一個orderInfo,變成這樣。

public void service(SomeThing toServed, OrderInfo orderInfo)

業(yè)務(wù)代碼里面充斥著這樣的代碼,寫的人不知疲倦,看的我心煩意亂了。
于是乎,我下定決心!要有一個日志框架,好好教人打日志

logger.info("req done" /*日志內(nèi)容*/)

必須像上面這樣寫日志代碼,其它的內(nèi)容全部實(shí)現(xiàn)自動填充!

設(shè)計(jì)原則

好!現(xiàn)在就來開始動手設(shè)計(jì)理想中的框架。但是在動手之前,還需要想清楚兩件事。

  1. 第一,要走的更遠(yuǎn),需要站在巨人的肩膀上。我無意實(shí)現(xiàn)一個跟log4j與logback之類雷同的框架。要利用上log4j或logback的特性,最好能兼容它們倆。
  2. 第二,一個好用的框架要做到稱手。要對普通開發(fā)人員透明,減少使用者的學(xué)習(xí)成本。

考慮到以上兩點(diǎn),并結(jié)合我們應(yīng)用常見的開發(fā)場景,我最終選定這個框架基于spring-boot實(shí)現(xiàn)。因?yàn)閟pring-boot提供了眾多實(shí)用的機(jī)制可供選擇。享受spring-boot帶來便利的同時,也為spring-boot做一些貢獻(xiàn),互利互惠。

基本概念

  1. 在我們系統(tǒng)中,一個應(yīng)用經(jīng)常能過HTTP或MQ與外部應(yīng)用溝通,我把溝通的內(nèi)容稱為消息
  2. 消息中攜帶了許多關(guān)鍵信息,如前面提到的OrderNo、TradeCode等,需要被記錄打印,我將其稱為關(guān)鍵字。
  3. 我將系統(tǒng)常用日志分為三類,分別是系統(tǒng)運(yùn)行日志消息日志、告警日志,它們各自輸出到不同的文件中。它們會被采集分析,分別服務(wù)于運(yùn)維人員、分析系統(tǒng)、監(jiān)控系統(tǒng)。由于對接系統(tǒng)不同,因此它們有各自的日志格式定義。

總體設(shè)計(jì)

日志框架示意圖

如圖展示,里層綠色為應(yīng)用層,指業(yè)務(wù)開發(fā)人員編寫的業(yè)務(wù)代碼;外層藍(lán)色部分為框架層,包含日志框架的各個功能模塊。

簡單地說,日志框架有以下要點(diǎn):

  1. 在請求進(jìn)入業(yè)務(wù)層之前進(jìn)行攔截,獲得消息(Message)。
  2. 根據(jù)關(guān)鍵字(Keyword),使用解析器(MessageResolver)提取消息(Message)中的值。關(guān)鍵字(Keyword)及其值保存于MDC之中。
  3. 打印日志時,將MDC中的值按格式自動填充到指定位置。
  4. 提供一個@MessageToLog注解,在函數(shù)上使用,將函數(shù)的返回值視作消息(Message),打印到消息日志中。
  5. 對系統(tǒng)運(yùn)行日志,消息日志,告警日志三種不同的日志類型,有各自的追加器(Appender),分別寫入到不同的文件中。

實(shí)現(xiàn)

具體代碼實(shí)現(xiàn),且聽下回分解。

日志框架系列講解文章
日志框架 - 基于spring-boot - 使用入門
日志框架 - 基于spring-boot - 設(shè)計(jì)
日志框架 - 基于spring-boot - 實(shí)現(xiàn)1 - 配置文件
日志框架 - 基于spring-boot - 實(shí)現(xiàn)2 - 消息定義及消息日志打印
日志框架 - 基于spring-boot - 實(shí)現(xiàn)3 - 關(guān)鍵字與三種消息解析器
日志框架 - 基于spring-boot - 實(shí)現(xiàn)4 - HTTP請求攔截
日志框架 - 基于spring-boot - 實(shí)現(xiàn)5 - 線程切換
日志框架 - 基于spring-boot - 實(shí)現(xiàn)6 - 自動裝配

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容