直到.net4.5,才有了比較便利的操作ETW的方法。
本文介紹的方法主要來源於Microsoft.Diagnostics.Tracing.TraceEvent官方資料庫。
准備
(1)需要用到類:Microsoft TraceEvent Library,這個類可以到nuget上下載到:
Install-Package Microsoft.Diagnostics.Tracing.TraceEvent
(2).net framework的版本要求在4.5以上
概念
圖中有三個角色:
(1)Event Session(事件會話)。事件提供者需要向控制器提交事件數據的元數據,控制器會將事件數據的元數據提供給事件消費者。它還可以控制是否接受事件提供者的事件提交。它對應Microsoft.Diagnostics.Tracing.TraceEventSession類。
(2)Event Provider(事件提供者),作用是引發事件,提供事件數據。它對應Microsoft.Diagnostics.Tracing.EventSource 類。
(3)Event Consumer(事件消費者),作用是消費事件。它對應Microsoft.Diagnostics.Tracing.TraceEventSource類。
創建ETW事件源(事件提供者)
創建一個繼承自EventSouce接口的類。注意類中成員方法Publish調用了基類的WriteEvent()方法,WriteEvent()多達13個的重載,這里選擇比較簡單的一個方法。如其字面所示,它的作用是將Event data(事件數據)寫入事件,如上圖所示。至於寫入的Event data是被保存在磁盤上,還是保存在內存中,取決於后續的session中的設置。
1 using System; 2 using System.Diagnostics.Tracing; 3 4 namespace WindowsFormsApplication2 5 { 6 7 public class MyEventSource : EventSource 8 { 9 public static MyEventSource Instance = new MyEventSource(); 10 11 public void Publish(string name) 12 { 13 base.WriteEvent(1, name); 14 } 15 } 16 }
創建會話,綁定事件源(事件提供者),訂閱事件源(事件消費者)
using Microsoft.Diagnostics.Tracing.Session; using Microsoft.Diagnostics.Tracing; private void button1_Click(object sender, EventArgs e) { Thread thread = new Thread(new ThreadStart(delegate { using (var session = new TraceEventSession("MySession")) { session.EnableProvider("MyEventSource"); // 使能事件源(事件提供者) session.Source.Dynamic.All += Dynamic_All; // 注冊事件處理函數(事件消費者) session.Source.Process(); // 等待事件產生 } })); thread.Start(); } /// <summary> /// 事件處理函數 /// </summary> /// <param name="obj"></param> void Dynamic_All(TraceEvent obj) { Console.WriteLine("event data" + obj.ToString()); }
細心的讀者可能會發現,在上面提到的三個角色中,事件消費者似乎沒有出現。實際上,它出現了,session.Source返回的是一個ETWTraceEventSource對象。ETWTraceEventSource繼承自TraceEventSource,就是事件消費者。
在會話被創建之后,在windows的性能監視器(控制面板=》管理工具)中,可以看到MySession位於“事件跟蹤會話”中,如下圖所示:
觸發事件
1 /// <summary> 2 /// 觸發事件 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void button2_Click(object sender, EventArgs e) 7 { 8 MyEventSource.Instance.Publish("leo"); 9 }
在執行這個方法之后,系統會調用上面所注冊的事件處理函數Dynamic_All(),且將事件數據"leo"一起傳入了,如下圖所示:
小結
在windows編程中,經常會遇到ETW,尤其是在日志和性能方面,經常可以看到ETW的身影。在接下來的文章中,我會介紹如何訂閱IIS產生的ETW事件。
查看 《IIS日志存入數據庫之二:ETW》
參考資料
Microsoft.Diagnostics.Tracing.TraceEvent
An End-To-End ETW Tracing Example: EventSource and TraceEvent
Application Analysis with Event Tracing for Windows (ETW)