logback自定義appender、policy實現日誌列印的邏輯處理
- 2019 年 10 月 5 日
- 筆記
以下只貼出核心程式碼,運行程式碼詳見 https://github.com/GloryXu
背景
目前所在的一個組為api介面平台,需要對註冊上的介面進行相應的性能監控。因為是中途接手的項目,對於介面性能的監控比較好奇,就花了點時間了解下,又學了一手,寫了個例子,記錄下。
程式碼結構概覽

文件名 |
說明 |
---|---|
LogbackMain |
應用main啟動類 |
LogPrint |
業務類(需要列印日誌的類) |
HandleAppender |
logback中自定義的appender處理類 |
MyPolicy |
自定義處理策略 |
HandleAppender類說明
// 注意:這邊的屬性名一定要與logback.xml中的標籤名一致 private MyPolicy myPolicy; // 同上 private Layout<E> layout; public void start() { super.start(); if (this.layout == null) { this.addStatus(new ErrorStatus("No layout set for the appender named "" + this.name + "".", this)); } } @Override protected void append(E eventObject) { if (this.myPolicy != null) { this.myPolicy.handler(this.layout.doLayout(eventObject)); } }
- 類屬性名與xml配置的標籤名相同是一個注意點,否則appender類中的屬性值為
null
LogPrint類說明
protected static final Logger mylogger = LoggerFactory.getLogger("myLogger"); private AtomicInteger count; public LogPrint(AtomicInteger count) { this.count = count; } private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1); public void printInfo () { pool.scheduleAtFixedRate(() -> { mylogger.info("print count " + count.incrementAndGet()); mylogger.debug("print debug level log!"); }, 1000, 5000, TimeUnit.MILLISECONDS); }
以上使用一個定時執行緒池固定頻率模擬業務系統列印日誌,觸發日誌訂製化處理功能
MyPolicy類說明
該類比較簡單,不再說明 詳細可查閱 Github
程式碼
logback.xml配置說明
<appender name="myLog" class="com.redsun.logback.HandleAppender"> <!--A.根據設置過濾日誌,此處設置的是info--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <!--B.自定義設置處理策略--> <myPolicy class="com.redsun.logback.MyPolicy"> <appName>monitor</appName> </myPolicy> <!--日誌列印格式,m:message--> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%m</pattern> </layout> </appender> <!--C.設置日誌級別為info--> <!--additivity=true,表示將日誌輸出出來,false則不會輸出日誌,但是appender仍可接收到輸出的日誌message--> <logger name="myLogger" level="info" additivity="true"> <!--指定自定義的appender來處理--> <appender-ref ref="myLog"/> </logger>
需要注意的點都已在xml注釋中說明,此處不再贅述
運行情況

在列印日誌前都會將需要列印的日誌發送至 MyPolicy
來的 handle
中處理一下,此時的邏輯就可以自定義了
缺點
我們項目的運用是在 handle
中將列印的日誌(介面的運行耗時,成功率等等)發送至 redis
中,然後會有另外的項目去定時任務的獲取數據並作計算,最終算出這個介面的運行情況。
那麼有什麼缺點呢,通過上面列印可以發現,列印的執行緒和真實跑業務的執行緒是同一個,如果自定義的日誌處理邏輯沒有任何的阻塞操作就還好,但是一旦有了耗時比較長的操作就會影響介面的性能了,遇到這種問題不熟悉的人往往很難定位到問題是如何產生的。可以根據業務需求,或者真實場景實現非同步化處理也未嘗不可,當然也要注意資源的分配和控制,不然因為次要功能影響了主要的業務功能就得不償失了。