.NetCore中的日誌(1)日誌組件解析

来源:http://www.cnblogs.com/durow/archive/2016/09/07/5850301.html
-Advertisement-
Play Games

.NetCore中的日誌(1)日誌組件解析 0x00 問題的產生 日誌記錄功能在開發中很常用,可以記錄程式運行的細節,也可以記錄用戶的行為。在之前開發時我一般都是用自己寫的小工具來記錄日誌,輸出目標包含控制台、文本文件、資料庫,一般都是創建全局的Logger,在需要記錄日誌的地方調用相應的Logge ...


.NetCore中的日誌(1)日誌組件解析

 

0x00 問題的產生

日誌記錄功能在開發中很常用,可以記錄程式運行的細節,也可以記錄用戶的行為。在之前開發時我一般都是用自己寫的小工具來記錄日誌,輸出目標包含控制台、文本文件、資料庫,一般都是創建全局的Logger,在需要記錄日誌的地方調用相應的Logger輸出至相應目標。遇到輸出目標多了有時候也感覺挺麻煩的,不過也還能接受。開始學習.NetCore後接觸到了日誌記錄框架(Logging組件),雖然完全可以用之前的方式記錄日誌,不過應該使用更通用的方式,把日誌記錄和具體的輸出目標解耦。所以學習了.NetCore中Logging組件,並嘗試實現了自定義的LoggerProvider,以及在.NetCore的Logging框架中使用現有完善的第三方日誌記錄工具NLog。寫一篇博客作為學習記錄,同時也希望對有這方面需求的園友有所幫助。

0x01 .NetCore中的Logging

正如在上面部分寫到的那樣,當日誌輸出的目標多起來後,寫日誌就會變得麻煩。仔細想一下,日誌輸出這個動作是不變的,變的只是不同的輸出目標(控制台、文本文件、資料庫等),所以可以把日誌記錄這個動作抽象出來,日誌記錄器包含多個可輸出目標,當我們調用Log方法寫日誌時,由Log方法依次調用Logger中的XxxLogger,把日誌寫到具體的目標上。過程如下圖所示:

那麼如何創建出這樣的一個Logger呢,我們可以創建一個工廠叫LoggerFactory用來生產Logger,Logger中包還含了ConsoleLogger、FileLogger等,這些XxxLogger可以通過XxxLoggerProvider創建。進一步的,可以把Logger、LoggerFactory和LoggerProvider的行為抽象為介面ILogger、ILoggerFactory、ILoggerProvider。

其中:

ILogger中的Log()方法可以記錄日誌;

ILoggerProvider可以創建ILogger,用於向特定的目標寫入日誌;

ILoggerFactory可以添加多個IloggerProvider,並可以創建我們最終使用的ILogger;

下圖為使用LoggerFactory中使用AddProvider方法添加ILoggerProvider:

下圖為LoggerFactory中使用CreateLogger方法創建Logger:

 

下圖為Logger的構造函數,使用傳入的LoggerFactory中的providers,依次調用其中的ILoggerProvider來創建XxxLogger。

 

這裡需要特別說明一下,ILoggerFactory和ILoggerProvider都產生ILogger,看上去讓人迷惑,但實際上這兩種ILogger的實現細節是不一樣的,不同的實現中Log()方法的意義不同。

對於ILoggerFactory產生的是Logger類型(也就是我們最終使用的Logger),其Log()方法是依次調用Logger中包含的_loggers數組中的ILogger。

而ILoggerProvider產生的為各類不同的XxxLogger(也就是上面說的Logger中的_loggers數組包含的如ConsoleLogger、DebugLogger),其Log()方法是把日誌寫到具體的目標上去。下圖為ConsoleLogger的Log()方法:

在有時候我們可能不希望某些日誌被寫入到所有的目標上。例如只想把某些特定的日誌寫入資料庫。這時可以在XxxdLoggerProvider構造函數中傳入

Func<string, LogLevel, bool> filter

形式的委托,當返回true時寫入日誌,返回false則不寫入日誌。

此外針對不同的LoggerProvider有不同的配置方式,這裡就不一一說明瞭。

0x02 泛型的Logger<T>

前面我們看到了,Logger用name來標識其唯一性。在日誌記錄時我們很多情況下都希望記錄日誌產生時所在的命名空間和類型,因此使用完整的類型名稱來作為Logger的name既保證了唯一性又記錄了日誌產生時所在的命名空間和類型是一個很好的選擇。當創建Logger<T>對象時,實際上就是創建了一個用T的完整類型名稱作為name的Logger併進行了包裝,把Logger<T>的Log方法原封不動傳入了創建的Logger的Log方法。

這樣一來像NLog這樣基於name的路由也很容易集成了。

0x03 使用日誌記錄

ILoggerFactory預設就已經被添加到IServiceCollection容器中了,我們只需要添加需要的ILoggerProvider即可。為了讓代碼更簡潔更具備自解釋的能力,Logging組件還給ILoggerFactory添加了擴展方法,例如只要使用以下代碼

就可以完成ConsoleLoggerProvider和DebugLoggerProvider的添加。

此外對Logger複雜的Log方法也進行了封裝(LogTrace、LogDebug、LogError等等),以滿足不同需求。

在使用Logger時可以通過依賴註入的方式獲取Logger,可以有兩種方法獲取:

以及

這兩種方法沒有本質區別,如下圖所示CreateLogger<T>方法也是調用Logger<T>構造函數來創建Logger<T>的。

所以只要根據喜好選擇就行。

0x04 寫在最後

.NetCore的Logging組件提供了日誌記錄的框架,只要實現了ILoggerProvider介面的日誌記錄工具都可以集成到Logger中,這極大方便了成熟的第三方日誌記錄工具的集成。通過Logging組件,把日誌記錄邏輯和具體的記錄行為解耦了,可以任意更換日誌記錄工具而不需要修改日誌記錄邏輯,同樣的,只要實現了框架的介面,不同日誌記錄工具也可以混用。所以雖然.NetCore本身只實現了Console、Debug等幾個有限的Logger,但藉助於豐富的第三方日誌記錄工具,我們有非常多的選擇。即使需求極其奇葩,只要實現框架中的介面,我們很容易集成自己寫的日誌記錄工具。下一篇將以NLog為例說一下第三方日誌記錄工具的集成,此外還將編寫和集成一個自己寫的Logger。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上一次介紹用 Xenocode Postbuild for .NET 混淆加密源代碼確保軟體安全,本篇將討論用 Eziriz .NET Reactor 混淆加密軟體源代碼,為從未用過該軟體加密的用戶分享net reactor使用方法,也就是平常說的net reactor使用教程。 還是那句話,用工具 ...
  • 註意:枚舉類型和結構體都屬於值類型。 結構體:就是一個自定義的集合,裡面可以放各種類型的元素,用法大體跟集合一樣。 一、定義的方法: struct student { public int nianling; public int fenshu; public string name; public ...
  • 自定義CheckBox樣式,mark一下,方便以後參考復用 設計介紹: 1、一般CheckBox模板太難看了,肯定要重寫其中的模板 2、模板狀態為未選中狀態和選中狀態,設置為預設未選中就好了。 預設狀態,設置邊框、透明度等 選中的話,我們可以設置√和背景。 當然如果需要點動畫的話,可以添加個Stro ...
  • 本節講述佈局,順帶加點樣式給大家看看~單純學佈局,肯定是枯燥的~哈哈 那如上界面,該如何設計呢? 1、一些佈局元素經常用到.Grid StackPanel Canvas WrapPanel等。如上這種佈局,在子元素數量未知的情況下,我們應該使用WrapPanel或者StackPanel來佈局,子元素 ...
  • ASP.NET MVC Core 的控制器可以利用視圖返回格式化結果。 ...
  • 預設情況下,ASP.NET應用程式以本機的ASPNET帳號運行,該帳號屬於普通用戶組,許可權受到一定的限制,以保障ASP.NET應用程式運行的安全。但是有時需要某個ASP.NET應用程式或者程式中的某段代碼執行需要特定許可權的操作,比如某個文件的存取,這時就需要給該程式或相應的某段代碼賦予某個帳號的許可權 ...
  • 代碼: 效果圖: ...
  • 雖然有很多話想多,但是提筆才發現自己的語言組織能力有多差,差到不知道從何說起。 今日如往常一樣的修改bug,遇到解決不了的問題直接複製到百度里。通過網路站在前人的肩膀上真的是一件非常爽的事情,基本上第一頁看不完就能把問題解決完,更爽的是,你既可以獲得清晰的步驟去解決想解決眼下的問題,又可以深究其原理 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...