1. 程式人生 > >Serilog 原始碼解析——總覽

Serilog 原始碼解析——總覽

## 背景 大家好,考慮到在最近這些天,閒來無事,找了個類庫好好研究下別人寫的高質量程式碼,頗有收穫,打算和大家分享下。考慮到最近在自學 ASP.NET Core 的相關開發,對 Serilog 這個日誌記錄庫使用較多,好奇其內部的實現原理,趁著這段鹹魚時間好好地研究了下 Serilog 的原始碼,順帶複習了一些常用的設計模式。目前計劃寫成一個系列介紹 Serilog 的實現,如有錯誤還請指正。 ## 日誌記錄 在分析原始碼前,我們首先要知道 Serilog 是什麼,它的功能是什麼,能做什麼事。俗話說知己知彼,百戰不殆。對對方都完全不瞭解,更別說去分析內部機理了。按照其官方定義,Serilog 是一個結構化的日誌記錄器。那麼,首先,日誌是什麼? 日誌,按照維基百科的說法,就是記錄了在系統執行期間發生的事件,以便於瞭解系統活動和診斷問題。換句話來說,日誌資訊揭露了部分的軟體執行流程。如果日誌記錄使用得當的話,它甚至還可以記錄當時日誌所處的上下文資訊,為未來系統分析提供了方便。舉個例子,使用者在登入系統時,如果在登入流程對登入事件進行合適記錄的話,我們在後期維護或者檢索時就可以知曉曾經有某個使用者嘗試登入該系統以及是否登入成功。 ```csharp // 虛擬碼 登入流程 { 記錄日誌:嘗試登入 判斷驗證碼是否正確; 記錄日誌:驗證碼正確/錯誤(返回); 嘗試連線使用者資料庫; 記錄日誌:使用者資料庫連線成功/失敗(返回); 查詢使用者名稱和密碼匹配情況; 記錄日誌:使用者密碼驗證成功/失敗(返回); 檢測使用者許可權; 記錄日誌:使用者登入成功/失敗; } ``` 上面是使用者登入過程的虛擬碼,我們通過安插幾條日誌記錄語句來記錄該登入流程的具體走向。比如說我們發現有一個使用者始終登入失敗,通過查詢其日誌的記錄資訊可以快速得知它在哪個過程出現了錯誤。這裡如果記錄使用者登入失敗這條語句,就可能表明該使用者的使用者名稱和密碼沒有問題,但是沒有足夠的許可權登入該系統。 那麼,何為結構化日誌呢?在以往的日誌記錄中,向日志記錄器中只需要將日誌訊息(log message)字串傳入,由記錄器向各目的地寫入對應的字串即可。然而,這樣的操作有其不方便性,日誌資訊的格式由呼叫方控制,沒有統一的日誌記錄格式,此外,資料被寫死在日誌字串中,不利於通過根據資料去查詢對應的日誌資訊(常利用正則去查詢匹配字串的日誌),缺乏靈活性。結構化的日誌是採用某種格式來記錄日誌而非原始的文字字串資訊,比如說Json、xml格式等,這種方法處理的好處在於具有更加靈活的格式控制以及查詢方法等。結構化日誌通常是包含日誌的文字和資料,二者共同組成日誌事件(log event),一次日誌記錄產生一個日誌事件,而日誌事件如何渲染成日誌,由具體的日誌實現所決定。 ## 思路 雖然說這篇部落格的標題叫做 Serilog 原始碼解析,但是一上來就直接說 xxx 類做了什麼、xxx 類擔任了什麼職責容易讓別人一頭霧水,在對功能都未清晰的情況下,直接拆解原始碼會讓未接觸過的人更加難以理解。因此,本系列並不打算一上來就對原始碼做拆解。 這裡,計劃通過以一個小 demo 為開頭,通過提需求的方式不斷改進 demo 來作為開篇。這樣做的好處有兩個,一個是能夠了解日誌記錄的核心功能有哪些,另一個是通過demo為後續的原始碼分析提供了基礎,快速理解類庫中的核心功能的實現邏輯。 這裡放出了 demo 的[原始碼](https://github.com/iskcal/LogDemo)。原始碼採用git來管理,併為不同版本添加了 tag,每個版本使用 v[num] 的形式,比如說v2版本就是 v2。只要用以下命令就可以檢視不同版本的原始碼。 ```bash git clone https://github.com/iskcal/LogDemo git checkout v[num] ``` 之後,介紹下 Serilog 常用的使用方法以及原始碼相關的準備工作,為後續的解析做鋪墊。最後,剩餘部分的內容將按照 Serilog 的功能對原始碼進行拆解。 ## 目錄 + [Serilog 原始碼解析——總覽](https://www.cnblogs.com/iskcal/p/introduction-to-the-source-code-of-serilog.html) + [Serilog 原始碼解析——demo實現(上)](https://www.cnblogs.com/iskcal/p/implementation-of-the-log-demo-1.html) + [Serilog 原始碼解析——demo實現(下)](https://www.cnblogs.com/iskcal/p/implementation-of-the-log-demo-2.html) 未完待續…… ## 總結 目前,Serilog 是一個非常廣泛應用在各種專案系統中的日誌類庫。Serilog 具有非常強的擴充套件性,它並沒有將所有功能全部放在Serilog這一個專案中而使得專案變得臃腫,相反,它通過將各種功能以擴充套件的形式分散成若干小專案,彼此單獨演化,不僅保持了最核心部分功能的穩定,也保證了使用時最小包大小的效果。從Serilog組織所維護的專案中可以發現,圍繞Serilog有60多子專案。在下一篇文章中,我會通過一個 demo 來展示下 Serilog 中最為核心的部分設計。