大家好,我是3y。在正文之前,先給各位股東彙報下austin項目進度:
總的來說,我感覺這次的反響是不錯的,雖然閱讀量不高。但留言的人多了很多,也有很多人都擔心我會不會鴿掉(更新一半中途就斷了)
我隻能說:别慌,絕對不鴿,你隻管追更就好。
我已經決定每個周末都扛着電腦回家,有空就往附近的圖書館裡跑(圖書館是學習的YYDS,在家的效率就是要比圖書館要低不少)
不多BB了,今天繼續聊個話題:日志
所謂日志,在我了解下就是:記錄程式運作時的資訊
在Java最初期又或是我們初學階段,列印日志全憑<code>System.out.println();</code>
這好用嗎?有待商榷。
對于大部分初學者來說,好用!我想看的資訊,直接在<code>console</code>就能看到了,這是多麼地友善阿。學習Java的第一個運作結果都是由<code>System.out.println();</code>出來的,不需要有任何的學習成本。
對于大部分工作者來說,本地調試可以,但如果程式部署到伺服器以後,那就算了。
生産環境跟本地環境是有差別的:
生産環境需要記錄的日志會更多(畢竟是作為一個系統/項目線上上運作,不可能隻列印一點點内容)
生産環境的日志内容需要保留至檔案(作為留存,線上不會說第一時間發現問題,很多需要查找曆史日志資料)
生産環境的日志内容需要有一定的規範格式(至少日志記錄的時間需要有吧)
…
上面這些要求,<code>System.out.println();</code>都是不具備的。
是以,我們可以看到在公司裡寫的項目,是沒有用<code>System.out.println();</code>記錄日志的
工作了以後,你會發現每次引入一個架構,這個架構下幾乎都有對應的日志包。
我之前在公司裡曾經整合過幾個項目(将原有的幾個工程合并到一個項目内)。
系統分久必合合久必分,當時是認為以前的同僚把項目拆得過于細,造成一定的資源浪費(畢竟每個工程跑線上上至少都會部署兩台線上機器),是以有段時間公司就希望我們把一些細小的項目進行合并。
至于這做得對與錯,這塊我就不談了。
在合并的過程中,最最最麻煩的就是解決依賴沖突的問題(都是Maven項目,會有Maven仲裁的問題),而這裡邊,最明顯的就是Java日志包的問題。
如果你有那麼一丢丢了解Java日志,你就應該多多少少聽說過以下的名字:Log4j(log for java)、JUL(Java Util Logging)、JCL(Jakarta Commons Logging)、Slf4j(Simple Logging Facade for Java)、Logback、Log4j2
如果你比較細心,你會發現,不同的技術架構所采用的Java日志實作都很有可能不一樣的。
既然實作不一樣,那對應的API調用是不是就不一樣?(畢竟它還不像是JDBC,定義了一套接口規範,各個資料庫廠商去實作JDBC規範,程式員面向JDBC接口程式設計就完事了)
那這這這不是亂套呢?想到這裡,血壓就逐漸就上來了?這别慌,上面提到的Java日志Slf4j(Simple Logging Facade for Java)幹的就類似JDBC做的事情。
它定義了日志的接口(門面模式),當項目使用别的日志架構時,那就适配它!(注意:JDBC是定義接口,資料庫廠商實作。Slf4j也定義了接口,但是它适配其他的Java日志實作,騷不騷?)
我們看Slf4j官網的一張圖,應該就挺好了解了:
扯了這麼久,我想表達的是:我們在項目中,最好是使用Slf4j提供的API,至于真實的LOG實作,都可以用Slf4j進行橋接(這樣一來,或許将來有一天說要從log4j改為logback,那程式代碼也不用改動)
還沒有過生産環境的開發的同學可能認為記錄日志就是用來定位問題的,其實并不完全是。
日志一方面我們用它來定位問題,一方面我們很多的資料也是來源于日志
不要覺得存在資料庫裡的資料才是重要的,我們程式運作時記錄下的日志資料也同樣重要。
在大資料領域裡,資料來源有很多:關系型資料庫、爬蟲、日志等等
舉個例子,我以前的公司就有處理日志的一套架構:
我們正常把日志資訊輸出到檔案下
架構提供背景給予我們配置(檔案的路徑以及Kafka Topic Name)
該架構做的事情說白了就是:把我們的日志檔案内容轉成Kafka消息(如果使用方需要将哪個日志檔案的内容轉為MQ消息,那在平台上配置下就完事了)
有了Kafka消息,那配合流式處理平台(Storm/Spark/Flink)再對日志進行清洗,是不是就能産生有價值的資料
扯了這麼久的日志基礎,隻是想讓還不了解日志的同學有個認知。
不扯别的了,還是回到我們還在「建立檔案夾」階段的austin項目吧。
austin項目的搭建技術架構使用的是SpringBoot,SpringBoot預設的日志組合是:<code>Slf4j + logback</code>
我在公司接觸到的項目幾乎都是這個組合,是以我就不打算動了,就直接用<code>logback</code>作為austin的日志實作架構了(要是真有那麼一天要改成别的日志實作,理論上隻要引入對應的橋接包就完事了)。
在無任何配置的前提下,隻要我們引入了SpringBoot的包,就能直接使用日志的功能了。具體效果入下圖
SpringBoot是約定大于配置的一個架構
SpringBoot會預設去加載resources下名為**logback.xml **或者 logback-spring.xml的配置檔案( xml 格式也可以改為 groovy 格式) 如果都不存在,那麼 logback 預設地會調用BasicConfigurator ,建立一個最小化配置。 最小化配置由一個關聯到根 logger 的ConsoleAppender 組成。輸出用模式為%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 的 PatternLayoutEncoder 進行格式化
從上面可以發現的是,預設的logback配置是不符合我們的要求的(它是列印在console的),我們是希望把日志記錄在檔案下的。
是以,我們會在<code>resources</code>下建立一個<code>logback</code>配置。常見的配置内容如下:
日志的配置不會是一成不變的,現在項目剛搭建出來,就怎麼簡單怎麼來。
這篇文章釋出的前一個晚上,ZhenDong突然問我現在用的什麼MQ比較多,我随口一答:Kafka吧,我接觸MQ基本都是Kafka
他說在寫一個好東西,到時候發出來。我這一聽,就肯定感興趣了啊。
ZhenDong發的文章連結:https://mp.weixin.qq.com/s/JC51S_bI02npm4CE5NEEow
文章大概就是美團大佬們他們用AOP+動态模闆封裝了一套SDK,進而優雅地記錄記錄檔(說人話就是:大佬不想日志寫在業務代碼上,難以管理。将寫日志這個動作抽象出來,用注解來統一記錄日志)
文章還是很精彩的,我推薦閱讀一遍。
ZhenDong大佬看完文章後,自己實作了一套,已經差不多快要完成了。順便我跟他讨論了下使用場景,感覺我的項目也可以用那一套東西(有優雅的打日志方式,誰不愛呢)
我已經預定了,到時候他給我發源碼,我就學習下實作思路(後面項目也用他提供的SDK來打日志,有問題就開噴🐶[狗頭.jpg])。等他忙完寫好文章,我也轉載下跟大家一起學習下。
像這種輪子或者說是經驗思路,自己學會了以後,就可以在面試的時候吹了。就說自己對項目系統改造了一把,從原來的破鬼樣(介紹背景) *,變成現在如此優雅(**得到的結果**),并這個過程中穿插自己的實作思路以及遇到的坑(**艱辛的過程**),這種亮點*哪個面試官又不愛呢?
日志在一個項目裡,我認為是在一個比較重要的位置上的。我們的資料和定位問題都離不開日志,有的項目的日志相當混亂,那維護起來就特别特别麻煩。
其實我完全可以自己寫個<code>logback</code>配置就把這塊給忽略了,但我還是堅持梳理出來,這篇文章按照「項目」的次元從頭梳理了一遍日志的知識,希望對大家有幫助吧。
項目源碼Gitee連結:https://gitee.com/austin
項目源碼GitHub連結:https://github.com/austin
關注我的微信公衆号【Java3y】來聊點不一樣的!
【對線面試官+從零編寫Java項目】 持續高強度更新中!求star
原創不易!!求三連!!
更多的文章可往:文章的目錄導航