ETW是Event Tracing for Windows的简称,它是Windows提供的原生的事件跟踪日志系统。由于采用内核(Kernel)层面的缓冲和日志记录机制,所以ETW提供了一种非常高效的事件跟踪日志解决方案。
一、ETW模型
事件监测(Event Instrumentation)总会包含两个基本的实体,事件的提供者(ETW Provider)和消费者(ETW Consumer),ETW框架可以视为它们的中介。ETW Provider会预先注册到ETW框架上,提供者程序在某个时刻触发事件,并将标准化定义的事件提供给ETW框架。Consumer同样需要注册到ETW框架上,在注册的时候可以设置事件的删选条件和接收处理事件的回掉。对于接收到的事件,如果它满足某个注册ETW Consumer的筛选条件,ETW会调用相应的回调来处理该事件。
ETW针对事件的处理是在某个会话(ETW Session)中进行的,ETW Session提供了一个接收、存储、处理和分发事件的执行上下文。ETW框架可以创建多一个会话来处理由提供者程序发送的事件,但是ETW Session并不会与某个单一的提供者绑定在一起,多个提供者程序可以向同一个ETW Session发送事件。对于接收到的事件,ETW Session可以将它保存在创建的日志文件中,也可以实时地分发给注册的消费者应用。ETW会话的开启和终止是通过 Session的开启和终止是通过ETW控制器(ETW Controller)进行管理的。除了管理ETW Session之外,ETW Controller还可以禁用(Disable)或者恢复(Enable)注册到某个ETW Session上的ETW Provider。
综上所述,整个ETW模型由ETW框架本身和ETW Provider、ETW Consumer以及ETW Controller组成,上图很好地展示了这四者之间的关系。出于篇幅的限制,我们只能对ETW作一个粗略的介绍,实际上ETW自身是一个非常强大的事件跟踪日志系统,有兴趣的朋友可以参阅相关的文档进行系统学习。
二、针对ETW的编程
.NET提供了一种比较独特并且简单的编程模式编写针对ETW的事件提供和消费程序。所谓的ETW Provider就是事件的提供者,它体现了事件的来源,对应着一个EventSource对象。EventSource类型定义在“System.Diagnostics.Tracing”这个NuGet包中。如下面的代码片段所示,EventSource类型中定义了一系列WriteEvent方法重载,这些方法会触发一个事件并将其递交给ETW框架。这些方法具有一个代表事件ID的参数,必须是一个介于[0, 65535] 之间的整数,而其他参数将作为负载(Payload)附加到事件对象上。
1: public class EventSource : IDisposable
2: {
3: ...
4: protected void WriteEvent(int eventId);
5: protected void WriteEvent(int eventId, int arg1);
6: protected void WriteEvent(int eventId, long arg1);
7: protected void WriteEvent(int eventId, string arg1);
8: protected void WriteEvent(int eventId, byte[] arg1);
9:
10: protected void WriteEvent(int eventId, int arg1, int arg2);
11: protected void WriteEvent(int eventId, int arg1, string arg2);
12: protected void WriteEvent(int eventId, long arg1, long arg2);
13: protected void WriteEvent(int eventId, long arg1, string arg2);
14: protected void WriteEvent(int eventId, long arg1, byte[] arg2);
15: protected void WriteEvent(int eventId, string arg1, int arg2);
16: protected void WriteEvent(int eventId,