1. 程式人生 > >.NET Core的日誌[5]:利用TraceSource寫日誌

.NET Core的日誌[5]:利用TraceSource寫日誌

從微軟推出第一個版本的.NET Framework的時候,就在“System.Diagnostics”名稱空間中提供了Debug和Trace兩個類幫助我們完成針對除錯和跟蹤資訊的日誌記錄。在.NET Framework 2.0中,微軟引入了TraceSource並對跟蹤日誌系統進行了優化,優化後的跟蹤日誌系統在.NET Core中又經過了相應的簡化。.NET Core的日誌模型藉助TraceSourceLoggerProvider實現對TraceSource的整合,在正式介紹這個Logger之前,我們先來認識一下TraceSource跟蹤日誌系統中的三個核心物件。[ 本文已經同步到《ASP.NET Core框架揭祕

》之中]

目錄
一、基於TraceSource的追蹤日誌系統
二、TraceSourceLogger
三、TraceSourceLoggerProvider

一、基於TraceSource的追蹤日誌系統

對於這個基於TraceSource的跟蹤日誌系統來說,除了TraceSource之外,它還具有額外連個核心的物件,它們分別是TraceListener和SourceSwitch,三者之間的關係如下圖所示。日誌訊息的寫入實現在TraceListener上,我們可以將一組TraceListener註冊到某個TraceSource之上。當我們利用TraceSource記錄某條跟蹤日誌時,日誌訊息會分發給註冊的每一個TraceListener並由它們將日誌訊息寫到對應的目的地。每個TraceSource都具有一個SourceSwitch,後者起到了日誌過濾的作用。具體來說,SourceSwitch定義了相應的過濾條件來幫助TraceSource決定是否應該將跟蹤日誌分發給TraceListener,如果指定的日誌訊息不滿足過濾條件,TraceSource將不會進行任何實質性的日誌記錄工作。

11

如下所示的是TraceSource的定義。每一個TraceSource都具有一個名稱,它一般代表寫入跟蹤日誌的應用程式、服務或者元件的名稱。我們可以呼叫它的三組Trace方法(TraceData、TraceEvent和TraceInformation)來記錄跟蹤日誌。由於這些方法都標註了一個ConditionaleAttribute特性並將條件編譯符“TRACE”,所以針對這些方法的呼叫只有在針對Trace模式編譯的應用中才是有效的。

   1: public class TraceSource
   2: {
   3:     public TraceListenerCollection Listeners { get; }
   4:     public string             Name { get; }
   5:     public SourceSwitch         Switch { get; set; }
   6:  
   7:     public TraceSource(string name);
   8:     public TraceSource(string name, SourceLevels defaultLevel);
   9:    
  10:     [Conditional("TRACE")]
  11:     public void TraceData(TraceEventType eventType, int id, object data);
  12:     [Conditional("TRACE")]
  13:     public void TraceData(TraceEventType eventType, int id, params object[] data);
  14:  
  15:     [Conditional("TRACE")]
  16:     public void TraceEvent(TraceEventType eventType, int id);
  17:     [Conditional("TRACE")]
  18:     public void TraceEvent(TraceEventType eventType, int id, string message);
  19:     [Conditional("TRACE")]
  20:      public void TraceEvent(TraceEventType eventType, int id, string format, params object[] args);
  21:  
  22:     [Conditional("TRACE")]
  23:     public void TraceInformation(string message);
  24:     [Conditional("TRACE")]
  25:     public void TraceInformation(string format, params object[] args);  
  26: }

通過TraceData、TraceEvent和TraceInformation這三個方法記錄的跟蹤日誌都具有一個通過列舉型別TraceEventType表示的事件型別,它相當於前面提到的日誌等級。TraceEventType的這些列舉項的值越小意味著等級越高,定義日誌等級的LogLevel則於此相反。在呼叫TraceData和TraceEvent方法時,我們需要顯式地為寫入的跟蹤日誌指定事件型別,而TraceInformation方法則預設使用Information型別。

   1: public enum TraceEventType
   2: {
   3:     Critical         = 1,
   4:     Error            = 2,
   5:     Warning          = 4,
   6:     Information      = 8,
   7:     Verbose          = 16,
   8: }

與TraceEventType列舉對應的還具有另一個名為SourceLevels的列舉,除了包含五種具體事件型別之外,還具有額外兩個選項All和Off,該列舉物件被SourceSwitch用來過濾日誌。在呼叫建構函式建立TraceSource的時候,我們可以指定一個SourceLevels列舉值作為預設的等級。如果這個等級未作顯式設定,建立的TraceSource採用的等級為Off,這意味著預設情況下針對追蹤日誌的記錄是禁止的。

   1: [Flags]
   2: public enum SourceLevels
   3: {
   4:     All             = -1,
   5:     Off             = 0,
   6:     Critical        = 1,
   7:     Error           = 3,
   8:     Warning         = 7
   9:     Information     = 15,
  10:     Verbose         = 31
  11: }

我們建立的TraceSource是指定(或者預設設定)的表示日誌等級的SourceLevels列舉會用來建立一個具有如下定義的SourceSwitch物件,TraceSource的Switch屬性返回的就是這麼一個物件。顧名思義,SourceSwitch是一個開關,它利用ShouldTrace方法決定了針對某種型別的跟蹤日誌的寫入操作是應該開啟還是關閉。如下面的程式碼片段所示,ShouldTrace方法返回的結果是根據通過Level屬性返回的跟蹤日誌等級計算出來的,表示跟蹤日誌等級的SourceLevels列舉正是最初正是由TraceSource在初始化時提供的。

   1: public class SourceSwitch : Switch
   2: {
   3:     public SourceLevels Level {get;set;}
   4:  
   5:     public SourceSwitch(string name);
   6:     public SourceSwitch(string displayName, string defaultSwitchValue);
   7:  
   8:     public bool ShouldTrace(TraceEventType eventType)
   9:     {
  10:         return ((base.SwitchSetting & eventType) > 0);
  11:     }    
  12: }

TraceSource物件自身並不負責針對跟蹤日誌的寫入,它僅僅將日誌的寫入請求分發給註冊的TraceListener並委託它們來完成寫日誌的功能。這些註冊到TraceSource上的TraceListenter被儲存到由它的Listeners屬性返回的集合物件中。所有的TraceListener都拍生於如下這個抽象的TraceListener型別,它定義瞭如下兩組TraceData和TraceEvent方法。當我們呼叫TraceSource的TraceData、TraceEvent和TraceInformation方法時,如果通過SourceSwitch判斷應該開啟針對當前跟蹤日誌的寫入功能,那麼註冊的TraceListener的TraceData或者TraceEvent方法將會被呼叫。

   1: public abstract class TraceListener : IDisposable
   2: {
   3:     ...
   4:     public virtual void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data);
   5:     public virtual void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data);
   6:  
   7:     public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id);
   8:     public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message);
   9:     public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args);
  10: }

接下來我們通過一個簡單的控制檯應用來演示如何建立一個TraceSource並使用它來記錄追蹤日誌。由於TraceSource定義在“System.Diagnostics.TraceSource”這個NuGet包中,我們需要在project.json檔案中需要按照如下的方式新增針對這個NuGet包的依賴。和前面演示的例項一樣,為了提供針對中文編碼的支援,我們不得不新增針對“System.Text.Encoding.CodePages”這個NuGet包的依賴。

   1: {
   2:   ...
   3:   "dependencies": {
   4:     "System.Diagnostics.TraceSource": "4.0.0",    
   5:     "System.Text.Encoding.CodePages": "4.0.1"
   6:   }
   7: }

由於TraceSource總是利用註冊在它上面的TraceListener來完成寫日誌的工作,所以我們按照如下的方式自定義了ConsoleTraceListener。顧名思義,ConsoleTraceListener旨在將分發給它的追蹤日誌輸出到控制檯上。如下面的程式碼片段所示,這個ConsoleTraceListener僅僅重寫了Write和WriteLine方法,它們呼叫定義在Console型別上的同名方法將格式化好的日誌訊息輸出到控制檯上。

   1: public class ConsoleTraceListener : TraceListener
   2: {
   3:     public override void Write(string message) => Console.Write(message);
   4:     public override void WriteLine(string message) => Console.WriteLine(message);
   5: }

我們在作為程式入口的Main方法中建立了一個TraceSource物件。在呼叫建構函式的時候,除了指定TraceSource的名稱(“Program”)之外,我們還設定了一個預設的追蹤日誌等級(Warning)。接下來我們建立了一個ConsoleTraceListener物件並將其註冊到TraceSource物件上。在此之後,我們呼叫TraceSource的TraceEvent方法記錄了三條追蹤日誌,它們採用的追蹤事件型別分別是Information、Warining和Error。

   1: public class Program
   2: {
   3:     public static void Main(string[] args)
   4:     {
   5:         //註冊EncodingProvider實現對中文編碼的支援
   6:         Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
   7:  
   8:         TraceSource traceSource = new TraceSource(nameof(Program), SourceLevels.Warning);
   9:         traceSource.Listeners.Add(new ConsoleTraceListener());
  10:  
  11:         int eventId = 3721;
  12:         traceSource.TraceEvent(TraceEventType.Information, eventId, "升級到最新.NET Core版本({0})", "1.0.0");
  13:         traceSource.TraceEvent(TraceEventType.Warning, eventId, "併發量接近上限({0}) ", 200);
  14:         traceSource.TraceEvent(TraceEventType.Error, eventId, "資料庫連線失敗(資料庫:{0},使用者名稱:{1})", "TestDb", "sa");
  15:     }
  16: }

該程式執行之後,我們利用TraceSource記錄的追蹤日誌將會被註冊的ConsoleTraceListener按照如下圖所示的形式輸出到控制檯上。由於我們在建立TraceSource的時候指定了一個預設的追蹤日誌等級Warning,所以只有不低於這個等級的兩條日誌才會顯示在控制檯上。

12

二、TraceSourceLogger

.NET Core的日誌模型利用一個定義在NuGet包“Microsoft.Extensions.Logging.TraceSource”中的TraceSourceLogger型別實現與TraceSource跟蹤日誌系統的整合。從如下面的程式碼片段我們不難看出,一個TraceSourceLogger物件實際上就是對一個TraceSource物件的封裝,在實現的Log<State>方法中,它會呼叫TraceSource的TraceEvent方法來完成針對日誌訊息的寫入工作。

   1: public class TraceSourceLogger : ILogger
   2: {
   3:     public TraceSourceLogger(TraceSource traceSource);
   4:     public IDisposable BeginScope<TState>(TState state);
            
           

相關推薦

.NET Core日誌[5]:利用TraceSource日誌

從微軟推出第一個版本的.NET Framework的時候,就在“System.Diagnostics”名稱空間中提供了Debug和Trace兩個類幫助我們完成針對除錯和跟蹤資訊的日誌記錄。在.NET Framework 2.0中,微軟引入了TraceSource並對跟蹤日誌系統進行了優化,優化後的跟蹤日誌系統

Asp.Net Core 輕鬆學-利用日誌監視進行服務遙測

前言     在 Net Core 2.2 中,官方文件表示,對 EventListener 這個日誌監視類的內容進行了擴充,同時賦予了跟蹤 CoreCLR 事件的許可權;通過跟蹤 CoreCLR 事件,比如通過跟蹤 CoreCLR 事件,可以瞭解和收集到比如 GC,JIT,ThreadPool,intre

ASP.NET Core 實戰:使用 NLog 將日誌資訊記錄到 MongoDB

 一、前言   在專案開發中,日誌系統是系統的一個重要組成模組,通過在程式中記錄執行日誌、錯誤日誌,可以讓我們對於系統的執行情況做到很好的掌控。同時,收集日誌不僅僅可以用於診斷排查錯誤,由於日誌同樣也是大量的資料,通過對這些資料進行集中分析,可以產生極大的價值。  在微服務的系統架構中,由於一個系

ASP.NET Core 實戰:使用 NLog 將日誌信息記錄到 MongoDB

uil cfg init com shutdown 右鍵 重新 系統 文件的   在項目開發中,日誌系統是系統的一個重要組成模塊,通過在程序中記錄運行日誌、錯誤日誌,可以讓我們對於系統的運行情況做到很好的掌控。同時,收集日誌不僅僅可以用於診斷排查錯誤,由於日誌同樣也是大量的

Asp.net Core全域性異常監控和記錄日誌

前言           系統異常監控可以說是重中之重,系統不可能一直執行良好,開發和運維也不可能24小時盯著系統,系統拋異常後我們應當在第一時間收到異常資訊。在Asp.net Core裡我使用攔截器和中介軟體兩種方式來監控異常。全域性異常監控的資料最好還是寫入資料庫,方便查詢。 配置NLog NLog配

.Net Core 3.0 使用 Serilog 把日誌記錄到 SqlServer

Serilog簡介 Serilog是.net中的診斷日誌庫,可以在所有的.net平臺上面執行。Serilog支援結構化日誌記錄,對複雜、分散式、非同步應用程式的支援非常出色。Serilog可以通過外掛的方式把日誌寫入到各種終端,控制檯、文字、Sqlserver、ElasticSearch,Serilog支援終

企業專案實戰 .Net Core + Vue/Angular 分庫分表日誌系統 | 簡單的分庫分表設計

#前言 專案涉及到了一些設計模式,如果你看的不是很明白,沒有關係堅持下來,寫完之後去思考去品,你就會有一種突撥開雲霧的感覺,所以請不要在半途感覺自己看不懂選擇放棄,如果我哪裡寫的詳細,或者需要修正請聯絡我,謝謝。 #建立專案 ##1.SDK安裝 我們開發用的vs版本是2019 .Net Core的版本

企業專案實戰 .Net Core + Vue/Angular 分庫分表日誌系統 | 控制反轉搭配簡單業務

# 教程預覽 [01 | 前言](https://www.cnblogs.com/HDONG/p/13517146.html) [02 | 簡單的分庫分表設計](https://www.cnblogs.com/HDONG/p/13517207.html) [03 | 控制反轉搭配簡單業務](https:

企業專案實戰 .Net Core + Vue/Angular 分庫分表日誌系統五 | 完善業務自動建立資料庫

# 教程預覽 [01 | 前言](https://www.cnblogs.com/HDONG/p/13517146.html) [02 | 簡單的分庫分表設計](https://www.cnblogs.com/HDONG/p/13517207.html) [03 | 控制反轉搭配簡單業務](https:

企業專案實戰 .Net Core + Vue/Angular 分庫分表日誌系統六 | 最終篇-通過AOP自動連線資料庫-完成日誌業務

# 教程預覽 [01 | 前言](https://www.cnblogs.com/HDONG/p/13517146.html) [02 | 簡單的分庫分表設計](https://www.cnblogs.com/HDONG/p/13517207.html) [03 | 控制反轉搭配簡單業務](https:

.net core中的那些常用的日誌框架(Logging篇)

### 前言 >日誌,在我們每個專案中是必不可少的,它不僅能在除錯的時候測試資料,而且在專案上線,也是我們排查錯誤的得力助手,那我就能談談,用的多的幾個日誌框架吧!如果有不對的地方,歡迎來指教錯誤,謝謝! ### Asp.Net Core日誌中Logging篇 >一看這個名字,大家也能猜到,這是微軟自帶的一

.net core中的那些常用的日誌框架(NLog篇)

### 前言 >咱們上回講到,.net core中內建的Logging日誌框架的使用,以及淺顯的講解,接下來,給大家介紹一個第三方日誌框架(NLog)。 ### NLog簡介 >NLog是適用於各種.NET平臺(包括.NET標準)的靈活,免費的日誌記錄平臺。NLog使寫入多個目標變得容易 。(資料庫,檔案,控

.net core中的那些常用的日誌框架(Serilog篇)

### 前言 >上文說到Nlog日誌框架,感覺它功能已經很強大,今天給大家介紹一個很不錯的日誌框架Serilog,根據我的瞭解,感覺它最大的優勢是,結構化日誌,它輸出的日誌是Json的格式,如果你使用的是Mongodb進行儲存日誌,那就是完美的結合,MongoDB也是文件式資料庫,儲存的格式很像JSON,也可

菜鳥入門【ASP.NET Core5:命令行配置、Json文件配置、Bind讀取配置到C#實例、在Core Mvc中使用Options

加載 中間 view tar public png 配置到 index 不同 命令行配置 我們通過vs2017創建一個控制臺項目CommandLineSample 可以看到現在項目以來的是dotnet core framework 我們需要吧a

Asp.net core 學習筆記 (Excel 讀)

environ org host asd combine openxml end create rop EPPlus 已經支持 .net core 了 https://www.nuget.org/packages/EPPlus https://github.com/JanK

ASP.NET Core 2.0利用Jwt實現授權認證

metrics 登錄驗證 cor new end exc csharp async time 背景 在微服務架構下,一般都會按不同的業務或功能將整個系統切分成不同的獨立子系統,再通過REST API或RPC進行通訊並相互調用,形成各個子系統之間的串聯結構。在這裏,我們將采

Asp.net core實戰5: 專案檔案結構分析

1.專案檔案包括以下幾個部分:   根目錄是一個解決方案 Dependencies是依賴項檔案 Properties儲存 launchSetting.json,是涉及到如何編譯、執行專案的相關配置檔案 wwwroot是ASp.net core專案唯一可以被直接訪問的專案

Asp.Net Core 輕鬆學-利用 Swagger 自動生成介面文件

前言     目前市場上主流的開發模式,幾乎清一色的前後端分離方式,作為服務端開發人員,我們有義務提供給各個客戶端良好的開發文件,以方便對接,減少溝通時間,提高開發效率;對於開發人員來說,編寫介面文件需要消耗大量的時間,並且,手動編寫的文件介面會由於需求的頻繁變動變得難以維護,這就需要一個在介面開發階段可以

Asp.Net Core 輕鬆學-利用xUnit進行主機級別的網路整合測試

前言     在開發 Asp.Net Core 應用程式的過程中,我們常常需要對業務程式碼編寫單元測試,這種方法既快速又有效,利用單元測試做程式碼覆蓋測試,也是非常必要的事情;但是,但我們需要對系統進行整合測試的時候,需要啟動服務主機,利用瀏覽器或者Postman 等網路工具對介面進行整合測試,這就非常的不

.Net core 2.0 利用Arrtibute獲取MVC Action來生成選單

public class ActionsConfig { /// <summary> /// 是否生成Actions /// </summary> public static bool GenerateCon