.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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...