读logback源码系列文章(五)——Appender --转载
原文地址:http://kyfxbl.iteye.com/blog/1173788
明天要帶老婆出國旅游幾天,所以這段時間暫時都更新不了博客了,臨走前再最后發一貼?
上一篇我們說到Logger類的info()方法通過層層調用,最后委托Appender來記錄日志,這篇博客我們就接著說一下,Appender組件是怎么記錄日志的?
實際上Appender可能是logback框架中最重要的組件之一,雖然Logger是記錄日志的接口,但是如果一個Logger沒有關聯到任何Appender的話,那么這個Logger就無法記錄任何信息。此外雖然logback提供了很多擴展點,但是在應用中,我們可能很少會擴展filter,很少擴展layout和encoder,但是我們擴展Appender的機會卻是很多的?
老規矩,首先上圖,看一下Appender的大圖景,這里要說明的是,實現Appender接口有2個base類,一個是AppenderBase,另一個是UnsynchronizedAppenderBase,這2個類非常接近,80%以上的代碼都是相同的。如果我們自己要自定義Appender的話,只要寫一個類繼承自這2個base類就好?
首先是有一個Appender接口,然后如上文所說,UnsynchronizedAppenderBase類實現了這個接口,但是它本身是一個抽象類,需要繼承它才能得到真正的實現類。Appender接口繼承了FilterAttachable接口,而UnsynchronizedAppenderBase類持有一個FilterAttachableImpl類,委托這個類來實現FilterAttachable接口里定義的方法?
然后OutputStreamAppender是繼承自UnsynchronizedAppenderBase的Appender實現類,雖然它已經不是抽象類了,但是實際也是不能直接使用的,它的實現類就是最常見的ConsoleAppender和FileAppender?
只要自己使用過logback的朋友都知道,appender元素下面還需要配置encoder元素,這里的Encoder接口就是對應這個encoder元素的,因為其實Appender組件還不是最終實際記錄日志信息的組件,它要委托encoder組件來完成LoggingEvent的格式化和記錄?
介紹完了大體的結構,我們接下來就看看,從Appender接口的doAppend()方法,是怎么一步步地最終記錄日志的
首先是UnsynchronizedAppenderBase里面的doAppend()方法,它主要是記錄了Status狀態,然后檢查Appender上的Filter是否滿足過濾條件,最后再調用實現子類的appender()方法。很眼熟是嗎,這里用到了一個設計模式——模板方法?
上面的代碼非常簡單,就不用說了,我們就直接看看實現類的append()方法是怎么實現的,這里我們選擇OutputStreamAppender實現類?
首先檢查一下這個Appender是否已經啟動,如果沒啟動就直接返回,如果已經啟動,則又進入一個subAppend()方法?
這個方法居然什么事也不干。。做了一些檢查以后,又進入writeOut()方法。。。?
writeOut()方法委托配置給它的Encoder組件來記錄?
到這里,終于完了。Encoder組件又委托其Layout組件來將LoggingEvent進行格式化,返回一個String,然后通過OutputStream.write()方法,把格式化之后的日志信息寫到目的地?
耐心看到這里的朋友,可能已經有點被繞暈了,怎么Appender需要這么麻煩嗎?其實我們這里說的只是ConsoleAppender的doAppend()全流程,并不是所有Appender都這么復雜的,當然也有一些更復雜的。。?
下面看一個簡單的Appender,就是我自己寫的MyAppender?
好吧,非常簡單是不是,如果把這個Appender配置到logback.xml中,那么當Logger.info()調用的時候,就會先走進AppenderBase類的doAppend()方法里,進行Filter校驗等等,然后進入MyAppender的append()方法,不做其他的操作,直接把message給打印到Console上。當然,由于這個類是極度簡化的,沒有Encoder和Layout,也就沒辦法控制輸出日志的時間,也沒有辦法對%thread等標記進行解析處理了。但是這個類可能可以很清晰地表達出,Appender組件是怎么工作的:由AppenderBase類來調用Filter鏈,然后由Appender實現類來委托Encoder解析LoggingEvent,再輸出到目的地?
這篇博客到這里就結束了。到目前為止,5篇博客是這樣的:?
1、首先介紹logback怎么和slf4j對接?
2、然后介紹logback的LoggerFactory,也就是LoggerContext是怎么創建的?
3、接下來介紹LoggerFactory怎么創建Logger?
4、然后是Logger怎么記錄日志,這其中涉及了級聯調用Appender,和調用TurboFilter來過濾的問題?
5、本篇博客又以最常見的ConsoleAppender為例子,介紹了Appender組件怎么把日志信息輸出到目的地?
下一篇博客的主題有多種分支,可以再講講DBAppender和FileAppender是怎么記錄日志的,作為這篇博客的補充,加深理解;也可以繼續深入下去,說說Encoder和Layout組件;或者回頭介紹一下logback是怎么初始化的?
等我陪老婆旅游回來,再繼續更新本系列
轉載于:https://www.cnblogs.com/davidwang456/p/4466936.html
總結
以上是生活随笔為你收集整理的读logback源码系列文章(五)——Appender --转载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 思考微内核--转载
- 下一篇: Hadoop家族学习路线图--转载