Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

08 May 2020

Windows的事件跟踪(ETW)框架文档阅读笔记

Event Tracing 文档阅读笔记。

ETW(Event Tracing for Windows)是Windows的事件跟踪记录框架。可以实时跟踪事件,也可以把跟踪的事件记录下来保存成文件。ETW记录的事件常常被用来做性能分析。

Windows提供的是核心的事件路由系统。ETW事件的提供者(Provider)和消费者(Consumer)可以是内核或者用户进程。

文档是关于如何在用户态使用ETW。在内核态使用ETW,参考[Tools for Software Tracing]以及Adding Event Tracing to Kernel-Mode Drivers

.NET TraceProcessing API可以在.NET代码中分析ETW的记录。更多参考Process ETW traces in .NET

What’s New in Event Tracing

TraceLogging构建在ETW之上,提供了一个简单的方法来注入代码,可用于.NET和WinRT。Provider Traits可以在标准的ETW提供者提供额外的注册信息。

About Event Tracing

ETW是Windows内核提供的事件跟踪机制,可以实时输出或者记录到文件。ETW可以动态开关,方便跟踪记录,无需重启目标电脑。

ETW的API分三部分:

  • Controllers,控制器,事件跟踪会话控制
    • 定义log文件的大小和存放位置,帮事件提供方启停会话。
    • 控制缓冲区大小,提供会话统计
  • Provider,事件提供方
    • 注册为事件提供方的程序可以进行事件输出
    • 提供方可以自主决定输出时机
    • 一个程序既可以是控制器也可以是提供方
  • Consumers,事件采集方
    • 对一个或者多个会话中的事件进行采集以及记录
    • 操作系统根据时间顺序发布事件
    • 跟踪方可以自主决定采集时机

事件提供方有四种类型:

  • MOF
    • 使用RegisterTraceGuids和TraceEvent 来注册和记录事件
    • 使用MOF classes来定义事件的结构
    • 只能被一个会话跟踪
  • WPP
    • 使用RegisterTraceGuids和TraceEvent 来注册和记录事件
    • 使用TMF文件(编译后成为.pdb文件)来定义事件结构。TMF文件由预处理器扫描源代码,从WPP宏的使用推导而成。
    • 只能被一个会话跟踪
  • 基于manifest的
    • 使用EventRegister和EventWrite注册和记录事件
    • 使用manifest来定义事件结构
    • 可以同时被8个会话跟踪
  • 基于TraceLogging的
    • 使用TraceLoggingRegister 和 TraceLoggingWrite 注册和记录事件
    • 事件包含自描述信息,不用额外的定义
    • 可以同时被8个会话跟踪

这四种提供者在底层都是用EventWrite/EventWriteEx(或者老的TraceEvent)来写入事件。区别在于写入事件的信息以及如何定义事件结构上。对于新写的程序,应该采用后面两种。

ETW事件有可能发生丢失,可能的原因如下:

  • 事件大小超过64K(头加载荷)。
  • ETW缓冲区小于事件大小
  • 对于实时输出,有可能采集速度够不上生成速度
  • 记录到文件的时候,硬盘写入速度赶不上记录的速度

Event Tracing Sessions

ETW的会话负责跟踪事件的生成,以及缓冲区的管理。控制器负责会话的启停。最有可以同时有64个正着进行的会话。这其中有两个特殊的会话:

对于常规会话,参考Configuring and Starting an Event Tracing Session

Device Drivers

对于如何在设备驱动,或者内核态上使用ETW。参考Event Tracing for WindowsWPP Software TracingWMI Event Tracing

Using Event Tracing

Controlling Event Tracing Sessions

Configuring and Starting an Event Tracing Session

EVENT_TRACE_PROPERTIES结构用来描述ETW会话的属性。为EVENT_TRACE_PROPERTIES分配的内存必须足够容纳其之后的记录文件的名字。

StartTrace函数可以启动这个会话。成功的话会返回SessionHandle ,LoggerNameOffset 是LOG文件名的偏移。EnableTrace和EnableTraceEx可以开启某个生产者。EnableTraceEx2 可以提供filtering功能。

TraceSetInformation可以给事件加上一些额外的信息。Retrieving Additional Event Tracing Data。一个事件生成者能支持的会话数目有限。后到的会话会挤掉对前面会话对事件生成者的使用。

对于基于manifest的生产者,可以使用下面的命令查看级别和关键字:

  • logman query provider-name
  • wevtutil gp provider-name

wevtutil ep可以遍历基于manifest的生产者。

在收集完事件之后,可以通过ControlTrace 的 EVENT_TRACE_CONTROL_STOP参数来停止。

例子参考Example that Creates a Session and Enables a Manifest-based Provider

Configuring and Starting a SystemTraceProvider Session

SystemTraceProvider是一个内核事件生成方,通过下面的命令可以追踪:

tracelog -start MySession -f c:\Kernel1.etl -eflag PROC_THREAD+LOADER+CSWITCH

Configuring and Starting the NT Kernel Logger Session

NT Kernel Logger会话是系统预设值的,用来追踪一系列系统事件,整个系统只能有一个。这个会话不需要使用EnableTrace开启,可以通过EnableFlags 来过滤内核事件。对于这个会话,StartTrace会返回ERROR_ALREADY_EXISTS。

Configuring and Starting an AutoLogger Session

AutoLogger可以追踪的是系统启动的时候,用户登录之前的事件。AutoLogger 和Global Logger的差别:

  • AutoLogger可以有多个
  • AutoLogger启动时会向事件的生成者提供通告
  • AutoLogger无法追踪内核事件

参考Configuring and Starting the Global Logger Session

Configuring and Starting a Private Logger Session

私有会话是运行在用户态,跟事件生成者在同一个进程。使用私有会话的好处是它不占用全局会话的名额(64)。

Updating an Event Tracing Session

举例子说明如何更新会话。

Retrieving Additional Event Tracing Data

举例子说明如何获取事件包含的额外信息。

Providing Events

虽然有标识告诉事件生成者其是否被启用或者禁用,但是这只是一个建议,事件生成者可以自由决定什么时候生成事件。

Writing Events

把来自不同组件的事件组合起来。

Publishing Your Event Schema

发布事件的结构范本。

Consuming Events

事件的采集者可以从一个或者多个生成者那里采集事件。事件可以实时采集,不过需要开启会话的实时采集模式。

Event Tracing Reference

事件追踪参考。

(草草结束之)

comments powered by Disqus