编写检测清单
应用程序和 DLL 使用检测清单来标识其检测提供程序以及提供程序写入的事件。 清单是包含标识提供程序的元素的 XML 文件。 约定是使用 .man 作为清单的扩展。 清单必须符合事件清单 XSD。 有关架构的详细信息,请参阅 EventManifest 架构。
检测提供程序是调用 EventWriteEx、EventWriteString 或 EventWriteTransfer 函数以将事件写入事件跟踪 (ETW) 跟踪会话或事件日志通道的任何应用程序或 DLL。 应用程序可以定义涵盖其写入的所有事件的单个检测提供程序,也可以定义应用程序的提供程序和每个 DLL 的提供程序。 应用程序在清单中定义的提供程序数仅取决于应用程序希望如何组织其写入的事件。
为每个 DLL 指定提供程序的优点是,随后可以启用和禁用各个提供程序以及它们生成的事件。 仅当 ETW 跟踪会话启用提供程序时,此优势才适用。 指定事件日志通道的任何事件始终写入该通道。
清单必须标识提供程序及其写入的事件,但通道、级别和关键字等其他元数据是可选的;是否定义可选元数据取决于谁将使用这些事件。 例如,如果管理员或支持人员使用从事件日志通道读取事件的 Windows 事件查看器等工具使用事件,则必须定义将事件写入到的通道。 但是,如果提供程序仅由 ETW 跟踪会话启用,则无需定义通道。
尽管级别、任务、操作码和关键字元数据是可选的,但应该使用它们对事件进行逻辑分组或存储。 对事件进行分组可帮助使用者仅使用感兴趣的事件。 例如,使用者可以查询级别为“关键”且关键字 (keyword) 为“写入”的所有事件,或查询特定任务写入的所有事件。
除了使用级别和关键字来使用特定类型的事件之外,ETW 跟踪会话还可以使用级别和关键字 (keyword) 元数据来告知 ETW 限制写入事件跟踪日志的事件。 例如,会话可以将事件限制为仅级别为“error”或“critical”且关键字 (keyword) 为“read”的事件。
提供程序可以定义会话用于根据事件数据筛选事件的筛选器。 使用 level 和 关键字,ETW 确定事件是否写入日志,但使用筛选器,提供程序使用筛选器数据条件来确定是否将事件写入该会话。 仅当 ETW 跟踪会话启用提供程序时,筛选器才适用。
以下部分演示如何定义清单的组件:
- 标识提供程序
- 定义写入事件的通道
- 定义提供程序写入的事件的严重性级别
- 定义提供程序执行的任务和操作
- 定义对提供程序写入的事件进行分类的关键字
- 定义提供程序用于筛选其写入的事件的筛选器
- 定义模板数据引用的名称/值映射
- 定义用于定义特定于事件的数据的模板
- 定义提供程序写入的事件
尽管可以手动创作检测清单,但应考虑使用 Windows SDK 的 \Bin 文件夹中包含的 ECManGen.exe 工具。 ECManGen.exe工具使用 GUI,指导你从头开始创建清单,而无需使用 XML 标记。 了解本节和 EventManifest 架构 部分中的信息,在使用该工具时将有所帮助。
如果使用 Visual Studio 作为 XML 编辑器,则可以将 EventManifest 架构添加到项目 (查看 XML 菜单) ,以利用 Intellisense、内联架构验证和其他功能,以便轻松准确地编写清单。
编写清单后,使用消息编译器验证清单并生成包含在提供程序中的资源和头文件。 有关详细信息,请参阅 编译检测清单。
以下示例演示完全定义的事件清单的框架。
<instrumentationManifest
xmlns="http://schemas.microsoft.com/win/2004/08/events"
xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<instrumentation>
<events>
<provider ...>
<channels>
<importChannel .../>
<channel .../>
</channels>
<levels>
<level .../>
</levels>
<tasks>
<task .../>
</tasks>
<opcodes>
<opcode .../>
</opcodes>
<keywords>
<keyword .../>
</keywords>
<filters>
<filter .../>
</filters>
<maps>
<valueMap ...>
<map .../>
</valueMap>
<bitMap ...>
<map .../>
</bitMap>
</maps>
<templates>
<template ...>
<data .../>
<UserData>
<!-- valid XML fragment -->
</UserData>
</template>
</templates>
<events>
<event .../>
</events>
</provider>
</events>
</instrumentation>
<localization>
<resources ...>
<stringTable>
<string .../>
</stringTable>
</resources>
</localization>
</instrumentationManifest>