在.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以上

 

概念

                       

图中有三个角色:

(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)

 

posted @   何德海  阅读(4661)  评论(4编辑  收藏  举报
编辑推荐:
· 聊一聊 C#前台线程 如何阻塞程序退出
· 几种数据库优化技巧
· 聊一聊坑人的 C# MySql.Data SDK
· 使用 .NET Core 实现一个自定义日志记录器
· [杂谈]如何选择:Session 还是 JWT?
阅读排行:
· 一个.NET开源、易于使用的屏幕录制工具
· 【经验】几种数据库优化技巧
· C#中 Task 结合 CancellationTokenSource的妙用
· Superpower:一个基于 C# 的文本解析工具开源项目
· 反微服务架构(A Macro Services Framework)
点击右上角即可分享
微信分享提示