不知道你有沒有經歷過被日志支配的恐懼?我就經歷過,以前在服務器上要找到一個請求經過所有鏈路的日志,并串聯起來發現真的好難,而且有了日志還沒用,最好還有有參數,有響應可以串聯起來整個業務邏輯,最大程度進行場景復原,那段找日志的時光真是不堪回首,令人難忘,好在后來我離開了再沒去服務器上看過日志了。
針對這種場景,怎么解呢?針對每次請求如果我們生成一個id,每次打印日志的時候都把這個id打印出來,那么當我們搜索每次請求的時候,根據這個id進行搜索就行了,本文也是基于這個思路來實現這個功能的。
請求鏈路
client ---> Tomcat ---> other API
為了簡化我們的請求邏輯,這里假設client訪問我們的tomcat,然后tomcat訪問外部服務
記錄請求參數以及響應
為了記錄請求參數以及響應結果,我們需要借助Filter來解決這個問題
記錄Restful請求以及響應
一般而言,我們的服務會調用其他服務,無論你是使用的dubbo還是http,我們都能通過攔截器來記錄請求和響應參數,我們以rest來進行舉例
?
由于我們的response是stream,我們想要消費多次(一次返回給調用者,一次用于記錄),所以我們必須對這個response進行封裝
?
Log4j2配置
?
至此,我們的日志記錄已經初具雛形了,這個時候當我們訪問后端請求時,就可以通過返回的requestId去服務器上查詢這次請求的鏈路日志
?
后臺日志如下
?
查詢時我們可以使用這樣的命令
cat api.log | grep ${requestId}
這樣就足夠了嗎?不,還不夠好。我們可以將我們的日志發送到ElasticSearch,然后通過Kibana進行搜索,這樣就不用每次查看日志都還要登錄服務器了
自定義Appender
由于需要將日志發送到ES,所以我們需要自定義appender來發送日志,一個簡單的appender的如下
?
然后在Log4j中進行如下配置即可
?
這里我的es使用的是本地安裝的es,所以在運行的時候需要先啟動es
在Kibana中查詢
?
至此,我們的日志平臺就搭建起來了,以后別人就別想那么容易的推鍋給你了。
所有的代碼我都上傳到了我的github: (
https://github.com/generalthink/code)
以供大家參考
總結
核心思想就是讓 requestId出現在需要記錄日志的各個地方,然后通過requestId串聯起來。
都看到這里了,不點個贊嗎?
作者|think123|掘金