转载

在.net中使用ETW事件的方法

直到.net4.5,才有了比较便利的操作ETW的方法。

本文介绍的方法主要来源于Microsoft.Diagnostics.Tracing.TraceEvent官方资料库。

准备

(1)需要用到类:Microsoft TraceEvent Library,这个类可以到nuget上下载到:

Install-Package Microsoft.Diagnostics.Tracing.TraceEvent

(2).net framework的版本要求在4.5以上

概念

在.net中使用ETW事件的方法

图中有三个角色:

(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位于“事件跟踪会话”中,如下图所示:

在.net中使用ETW事件的方法

触发事件

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"一起传入了,如下图所示:

在.net中使用ETW事件的方法

小结 

在windows编程中,经常会遇到ETW,尤其是在日志和性能方面,经常可以看到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)

正文到此结束
Loading...