创建“感兴趣的区域”文件

“感兴趣的区域”文件是包含以下节点的有效 XML 文件:

  • InstrumentationManifest

  • 检测

  • 区域

  • RegionsRoot:适用于所有已定义区域的容器

  • 一个或多个 Region 节点

注意

在区域定义中,XML 声明中的 version 属性(如 version='1.0')是可选的。

下面的示例是定义简单区域的完整“感兴趣的区域”文件。 该示例之后介绍 Region 内的属性和节点说明。

<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<?Copyright (c) Microsoft Corporation. All rights reserved.?>
<InstrumentationManifest>
   <Instrumentation>
      <Regions>
         <RegionRoot Guid="{EFA7A927-BAE3-48F6-92E1-000000000000}"
                     Name="Sample Region File Root"
                     FriendlyName="Root">
            <Region Guid="{d8d639a0-cf4c-45fb-976a-000111000100}"
                    Name="FastStartup-Suspend-UserSession-Shutdown"
                    FriendlyName="User Session Shutdown">
               <Start>
                  <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="301" Version="0" />
               </Start>
               <Stop>
                  <Event Provider="{331c3b3a-2005-44c2-ac5e-77220c37d6b4}" Id="22" Version="0" />
               </Stop>
            </Region>
         </RegionRoot>
      </Regions>
   </Instrumentation>
</InstrumentationManifest>

定义区域

区域定义在 Region 节点中包含以下属性:

  • Guid(必需),该区域的 GUID。

  • Name(必需),该区域的唯一名称。 建议的 Name 格式为 Root-GrandparentName-ParentName-RegionName

  • FriendlyName(可选),它是区域的备用名称。

区域类型

可以根据其启动和停止的方式创建以下类型的区域:

基于事件的区域

最常见的区域类型是由事件定义起点和终点的区域。

若要将事件指定为起点或终点,需要提供以下属性:

  • Provider:指定事件提供程序 ID 的 GUID。

  • Id:指定事件 ID 的无符号短整型。

  • Version:指定事件版本的无符号字符型。

此外,还可以通过添加一个或多个 PayloadIdentifier 节点来进一步优化定义。 这些标记包含两个字符串属性,FieldName 和 FieldValue,指定事件必须包含的字段。 下面的“使用有效负载字段来标识事件”进一步介绍了 PayloadIdentifier 标记。

示例

下面是此类型区域的基本示例:

<Region Guid="{d8d639a0-cf4c-45fb-976a-000111000100}"
        Name="FastStartup-Suspend-UserSession-Shutdown"
        FriendlyName="User Session Shutdown">
   <Start>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="301" Version="0" />
   </Start>
   <Stop>
      <Event Provider="{331c3b3a-2005-44c2-ac5e-77220c37d6b4}" Id="22" Version="0" />
   </Stop>
</Region>

在下面的示例中,仅当指定的事件包含名为 StartOrStop、值为 Stop 的字段时,区域才结束:

<Region Guid="{d8d639a0-cf4c-45fb-976a-000111000100}"
        Name="FastStartup-Suspend-UserSession-Shutdown"
        FriendlyName="User Session Shutdown">
   <Start>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="301" Version="0" />
   </Start>
   <Stop>
      <Event Provider="{331c3b3a-2005-44c2-ac5e-77220c37d6b4}" Id="22" Version="0" />
      <PayloadIdentifier FieldName="StartOrStop" FieldValue="Stop" />
   </Stop>
</Region>

基于持续时间的区域

许多 ETW 事件定义为具有持续时间有效负载字段的单个停止事件。 我们可以通过从停止事件时间中减去持续时间来计算起点。

可以在 Start 或 Stop 标记中使用 Duration 标记来指定要从中获取持续时间信息的有效负载字段。 如果为起点定义持续时间,则从终点减去该持续时间。 如果为终点定义持续时间,则向起点添加该持续时间。

Duration 元素具有以下属性:

  • Provider:一个 GUID,指定包含有效负载字段的事件的提供程序 ID。

  • Id:指定包含有效负载字段的事件的 ID 的无符号短整型。

  • Version:指定包含有效负载字段的事件版本的无符号字符型。

  • Duration:指定有效负载名称字段的字符串。

  • Multiplier。 WPA 要求以毫微秒为单位的持续时间。 默认乘数为 1000000 (100 万) ,这将毫秒转换为纳秒。

如果为起点定义持续时间,则从终点减去该持续时间。 如果为终点定义持续时间,则向起点添加该持续时间。

示例

下面的示例定义一个区域,该区域在另一个区域启动时停止。 若要计算起点,我们将从终点减去持续时间。 持续时间可在 HiberHiberFileTime 有效负载字段中找到。 然后,将持续时间乘以 1,000,000,将其转换为毫微秒,并从终点减去它。

<Region Guid="{7D6BA3F6-BC04-4776-8A7F-93CF7F4E2B6D}"
   Name="FastStartup-Suspend-WriteHiberFile"
   FriendlyName="Subscribers for Create Session">
   <Region Guid="{93783B2C-A67F-49cb-89BC-BF305D7E2CEA}"
         Name="FastStartup-Suspend-Winlogon-CreateSession-Subscribers-Child"
         FriendlyName="Hiberfile Write">
      <Start>
         <Duration Provider="{331c3b3a-2005-44c2-ac53-77220c37d6b4}" 
                   Id="117"
                   Version="0"
                   Duration="HiberHiberFileTime"
                   Multiplier="1000000" />
      </Start>
      <Stop>
         <Region RegionGuid="{EC1BB2D9-4AA8-4d82-84AA-6042FF4CFBE3}" />
      </Stop>
   </Region>
</Region>

基于其他区域的区域

可以通过使用 Start 或 Stop 节点中的 Region 节点来定义一个区域,该区域的起点和终点由其他区域定义。 这个 Region 节点有一个必需的属性,RegionGuid,该属性指定目标区域的 GUID。

默认情况下,当起点区域停止时,其起点基于另一个区域的区域将启动。 同样,当终点区域启动时,其终点基于另一个区域的区域将停止。 可以通过向 Region 节点添加可选属性 Endpoint 来重写此默认行为。 Endpoint 可以具有 StartStop 值,并指定要用于启动或停止事件的区域的终结点。

示例

以下区域定义包含由其他区域定义的起点和终点:

<Region Guid="{93783B2C-A67F-49cb-89BC-BF305D7E2CEA}"
        Name="FastStartup-Suspend-HiberInitTime"
        FriendlyName="Hiberfile Initialization">
   <Start>
      <Region RegionGuid="{5E81D74C-0CCC-43f9-8119-953F827BCD12}" />
   </Start>
   <Stop>
      <Region RegionGuid="{7D6BA3F6-BC04-4776-8A7F-93CF7F4E2B6D}" />
   </Stop>
</Region>

作为其他区域容器的区域

包含其他区域的区域称为容器。 容器在所包含区域的第一个实例开始时启动,并在最后一个实例停止时停止。 这些区域没有任何其他属性。

RegionRoot 是你定义的所有区域的容器。 因此,当区域的第一个实例启动时,RegionRoot 将开始,并在区域的最后一个实例停止时停止。

若要定义容器区域,只需定义一个区域,而无需起点或终点。

示例

在下面的示例中,创建会话订阅者是创建会话子订阅者的容器。 请注意,创建会话订阅者没有起点或终点。 它在子区域的第一个实例开始时启动,并在子区域的最后一个实例停止时停止。

<Region Guid="{A75D8F5D-E8F8-40b8-B453-5CC70DEAC06F}"
   Name="FastStartup-Suspend-Winlogon-CreateSession-Subscribers"
   FriendlyName="Subscribers for Create Session">
   <Region Guid="{93783B2C-A67F-49cb-89BC-BF305D7E2CEA}"
           Name="FastStartup-Suspend-Winlogon-CreateSession-Subscribers-Child"
           FriendlyName="Child of Subscribers for Create Session">
      <Start>
         <Region RegionGuid="{5E81D74C-0CCC-43f9-8119-953F827BCD12}" />
      </Start>
      <Stop>
         <Region RegionGuid="{7D6BA3F6-BC04-4776-8A7F-93CF7F4E2B6D}" 
                 Endpoint="Stop" />
      </Stop>
   </Region>
</Region>

使用有效负载字段标识事件

通常,事件 ID 属性(进程 ID、线程 ID 和活动 ID)不足以识别特定方案。 例如,当服务启动时,将触发一个一般事件,该事件可能不会标识启动的服务。 出现这种情况时,必须依赖有效负载字段以获取其他信息。 在这种情况下,其中一个附加字段应包含服务名称。 可以使用此信息来进一步指定区域的起点和终点。

若要使用有效负载字段作为附加事件标识符,请将一个或多个 PayloadIdentifier 节点添加到 Start 或 Stop 节点。

PayloadIdentifier 节点具有以下属性:

  • FieldName(必需),即有效负载字段的名称。

  • FieldValue(必需),即有效负载的值。

  • FieldValueRelationship(可选)。 使用 IsEqual 指定事件必须包含有效负载值。 使用 DoesNotContain 指定事件不能包含有效负载值。 如果未指定该属性,则默认值为 IsEqual。

注意

有效负载字段区分大小写,并且 XML 定义必须与有效负载值完全匹配。 例如,如果有效负载字段的值为 00000,则区域定义还必须指定 00000 作为有效负载值。

示例

下面的示例包含起点和终点的 PayloadIdentifier 节点:

<Region Guid="{AB719FB1-D863-4305-AE8E-F21281899A85}"
        Name="FastStartup-ConsoleSessionDisconnect"
        FriendlyName="Console Session Disconnect">
   <Start>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="801" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="8" />
      <PayloadIdentifier FieldName="Key" FieldValue="00000" />
   </Start>
   <Stop>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="802" Version="0" />
      <PayloadIdentifier FieldName="Event"
                         FieldValue="20"
                         FieldValueRelationship="DoesNotContain" />
   </Stop>
</Region>

区域的匹配事件

WPA 将开始事件与停止事件相匹配,以在称为事件匹配的进程中形成区域。 在事件级别,WPA 尝试根据提供程序 ID、事件 ID、事件版本和任何其他指定的有效负载字段匹配单个开始或停止事件。

还可以将匹配扩展到区域级别,其中可以指定起点和终点都必须满足的条件。 在区域级别,可以要求这两个点具有匹配的线程 ID、进程 ID 和活动 ID。 此外,还可以在区域级别定义有效负载条件。

可以通过在 Region 节点内包含 Match 节点来使用区域级别匹配。 Match 节点包含子节点 Event,它可以具有以下属性的任意组合:

  • TID="true" - 需要匹配的线程 ID

  • PID="true" - 需要匹配的进程 ID

  • AID="true" - 需要匹配的活动 ID

Event 节点可以有一个可选的 Payload 子节点,该子节点包含 FieldName 属性。 此节点要求起始节点和停止节点都包含指定 FieldName 的匹配有效负载值。

或者,Payload 节点还可以包含可选属性 TargetFieldName。 如果指定了此属性,则 FieldName 仅对应于起始节点中的有效负载字段,而 TargetFieldName 对应于停止节点中的有效负载字段。

示例

以下示例在开始事件包含有效负载字段 SubscriberName 时形成一个区域,其值与停止节点中的有效负载字段值 Client 匹配。 开始和停止事件还必须具有匹配的线程 ID。

<Region Guid="{A75D8F5D-E8F8-40b8-B453-5CCC70DEAC06F}"
        Name="FastStartup-Suspend-Winlogon-CreateSession-Subscribers"
        FriendlyName="Subscribers for Create Session">
   <Start>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="805" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="0" />
   </Start>
   <Stop>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="806" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="0" />
   </Stop>
   <Match>
      <Event TID="true">
         <Payload FieldName="SubscriberName" TargetFieldName="Client" />
      </Event>
   </Match>
</Region>

根据条件筛选区域

WPA 可以基于条件或触发器(可以是事件或其他区域)包含或排除区域。 触发器在 Filter 元素中指定,包含 Filter 的区域是目标区域。

如果触发器是区域,则 Filter 必须包含区域 ID。

如果触发器是事件,则 Filter 必须包含一个 Event 元素,其中包含 ETW 提供程序的 ProviderId 和以下一个或多个属性:Id、Version、OpCode 和 Type。

在前面的区域类型中介绍了 Id 和 Version。 OpCode 是你选择的任何值。 Type 指定筛选目标区域的模式,可以根据下表所述的条件包括或排除它。

过滤器类型 说明
发现触发事件或区域时,排除目标区域。
OutPost 当目标发生于最近的触发事件或区域之后时,排除目标区域。
OutPrev 当目标发生于第一个触发事件或区域之前时,排除目标区域。
仅在发现触发事件或区域时包含目标区域。
InPost 仅在最近触发事件或区域后发生时包含目标区域。
InPrev 仅在第一个触发事件或区域之前发生时包含目标区域。

父子关系

可以在另一个区域中定义一个区域,以创建父子关系。 若要使区域成为父区域,其开始时间必须早于或等于子区域的开始时间。 它的停止时间还必须具有晚于或等于子区域的停止时间。 如果不满足这些条件,就不能形成父子关系。

若要为父区域指定其他条件,请使用 Match 节点中的 Parent 节点。 Parent 节点的属性和子节点与区域级匹配中使用的 Event 节点相同。 可以指定父区域和子区域必须具有相同的线程 ID、进程 ID、活动 ID 和任意数目的匹配有效负载字段。

使用有效负载字段时,如果仅指定 FieldName 属性,则父区域和子区域必须具有与该字段匹配的有效负载值。 如果还指定了 TargetFieldName 属性,则 TargetFieldName 属性将应用于父区域和子区域,这意味着子区域必须具有与父区域中 TargetFieldName 字段的有效负载值匹配的 FieldName 字段的有效负载值。

如果子区域具有多个潜在的父区域,则选择具有最早开始时间的父区域。

示例

下面的示例定义父区域条件。 父区域必须具有匹配的线程 ID,子区域中的 SubscriberName 字段的有效负载值必须与父区域中的 Client 字段值匹配。

<Region Guid="{A75D8F5D-E8F8-40b8-B453-5CC70DEAC06F}"
        Name="FastStartup-Suspend-Winlogon-CreateSession-Subscribers"
        FriendlyName="Subscribers for Create Session">
   <Start>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="805" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="0" />
   </Start>
   <Stop>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="806" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="0" />
   </Stop>
   <Match>
      <Event TID="true">
         <Payload FieldName="SubscriberName" TargetFieldName="Client" />
      </Event>
      <Parent TID="true">
         <Payload FieldName="SubscriberName" TargetFieldName="Client" />
      </Parent>
   </Match>
</Region>

自嵌套区域

自嵌套是优化父子关系的可选功能。

自嵌套区域是持续时间完全包含在同级区域的持续时间内的区域。 此区域实际上成为其持续时间较长的同级区域的子区域。

例如,假设为以下区域启用了自嵌套:

  • 父区域 A

  • 子区域 B1,开始时间为 0,停止时间为 6

  • 子区域 B2,开始时间为 2,停止时间为 5

  • 子区域 B3,开始时间为 3,停止时间为 4

此示例中,B2 成为 B1 的子区域,B3 成为 B2 的子区域。 创建此类型的父子关系时,将选择开始时间最接近子区域开始时间的父区域。

若要激活自嵌套,请在 Match 节点中添加一个 SelfNest 节点。

SelfNest 节点没有必需的参数。 但是,可以使用用于创建普通父子关系的相同匹配参数。 有关详细信息,请参阅本主题前面的“父子关系”。

示例

以下示例定义仅调用自嵌套的 Match 标记:

<Match>
   <SelfNest />
</Match>

以下示例定义更复杂的自嵌套方案,该方案需要匹配的线程 ID 和有效负载字段:

<Match>
   <SelfNest TID="true">
      <Payload FieldName="SubscriberName" />
   </SelfNest>
</Match>

实例名称

可以使用 Naming 节点为匹配区域的每个实例分配唯一名称。 如果在同一区域具有大量实例,或者需要根据其他条件对区域进行分类,则 Naming 非常有用。 实例名称可以基于有效负载字段,也可以基于与其他区域的关系。

通过使用 Naming 节点中的 PayloadBased 节点,可以基于有效负载值命名实例。 PayloadBased 节点有一个必需的属性 NameField,它指定要将其值用作实例名的有效负载字段。 这些有效负载字段可以位于区域的起点或终点。

下面是具有基于有效负载的 Naming 节点的区域示例:

<Region Guid="{9261872F-D3A7-4d80-BDE3-8479CC920639}"
        Name="FastStartup-Suspend-Winlogon-EndShell-CallSubscriber"
        FriendlyName="Call Subscriber for End Shell">
   <Start>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="811" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="13" />
   </Start>
   <Stop>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="812" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="13" />
   </Stop>
   <Match>
      <Event PID="true" />
      <Parent PID="true" />
   </Match>
   <Naming>
      <PayloadBased NameField="SubscriberName" />
   </Naming>
</Region>

在上一示例中,Naming 节点指示开始事件或停止事件包含名为 SubscriberName 的有效负载字段。 对于创建的区域的每个实例,实例名称是关联的有效负载值。

注意

命名区域实例时,WPA 首先检查开始事件是否具有匹配的有效负载字段。 如果找不到有效负载,WPA 将搜索有效负载字段的停止事件。 如果在两个事件中均找不到匹配项,则会向控制台输出错误。

有时,有效负载中的信息并不是我们想要的唯一信息。 例如,如果包含的有效负载中的信息是设备 ID,我们可能希望将此信息映射回设备说明和名称。 支持的 Type 属性包括:

  • Device,关联名称和说明

  • GUID,将 GUID 与区域关联

  • CLSID,将类名与类 ID 关联

  • PID,将进程名称与区域关联

<Naming>
   <PayloadBased NameField="SubscriberName" Type="Device" />
</Naming>

如果可以在起点和终点找到有效负载值,可以使用可选的 InstanceEndpoint 属性来指定要使用哪个点。 InstanceEndpoint 的可能值为 StartStop

<Naming>
   <PayloadBased NameField="SubscriberName" InstanceEndpoint="Start" />
</Naming>

还可以根据与其他区域的关系来命名区域。 若要与另一区域关联,请向 Naming 节点添加 RegionBased 节点。 RegionBased 节点具有四个必需属性:

  • RegionGuid:关联区域的 GUID。

  • Relation:一个条件值,用于描述要定义的区域与要关联的区域之间的关系。 目前,唯一支持的关系是 IsPresent,这意味着如果在跟踪中的某一位置找到关联区域,则条件为 true。

  • IfRelationTrue:Relation 描述的关系为 true 时,用作实例名称的字符串值。

  • IfRelationFalse:Relation 描述的关系为 false 时,用作实例名称的字符串值。

以下示例定义具有基于区域命名的区域。 如果在跟踪中的某一位置找到具有匹配 GUID 的区域,则 Launch 的每个实例均命名为 Warm。 否则,每个实例都命名为 Cold

<Region Guid="{C99EFA90-F645-4A24-9576-740351171BD0}"
        Name="WinStoreAppActivationDuration"
        FriendlyName="Launch">
   <Start>
      <Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="5901" Version="0" />
      <PayloadIdentifier FieldName="SqmableContractID" FieldValue="Windows.Launch" />
   </Start>
   <Stop>
      <Event Provider="{315a8872-923e-43a2-9889-33cd4754bf64}" Id="5902" Version="0" />
      <PayloadIdentifier FieldName="SqmableContractID" FieldValue="Windows.Launch" />
   </Stop>
   <Match>
      <Event PID="true" />
   </Match>
   <Naming>
      <RegionBased RegionGuid="{1539A93E-129C-4602-A011-431E7F73A353}" Relation="IsPresent" IfRelationTrue="Warm" IfRelationFalse="Cold" />
   </Naming>
</Region>

注意

将鼠标悬停在“感兴趣的区域”关系图中的区域实例上,可以看到 WPA 中的实例名称。

元数据

可以将其他信息以元数据的形式添加到区域定义,这些信息包含在元数据 Metadata 节点中。 例如,可以在元数据中包含说明区域条件的信息,以便其他用户能够更轻松地理解区域的用途。 元数据只是附加数据,它不会影响区域的处理。

WPA 将此元数据添加到“感兴趣的区域”关系图的图表视图中的每个区域实例中。 若要查看 WPA 中匹配事件的元数据,只需在图表视图中展开区域,然后滚动到所需的元数据。 WPA 为元数据分配唯一编号,节点的名称显示为列信息。

示例

以下示例在区域定义中包含 Metadata 节点:

<Region Guid="{F466EE67-192C-4772-B13D-052CCD2D70B3}"
        Name="FastStartup-Suspend-Winlogon-Logoff-Subscribers"
        FriendlyName="Subscribers for Logoff">
   <Start>
      <Event Provider="{dbe9b383-7cf3-4331-91cc-a3cb16a3b538}" Id="805" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="3" />
   </Start>
   <Stop>
      <Event Provider="{db39b383-7cf3-4331-91cc-a3cb16a3b538}" Id="806" Version="0" />
      <PayloadIdentifier FieldName="Event" FieldValue="3" />
   </Stop>
   <Match>
      <Event>
         <Payload FieldName="Event" />
      </Event>
   </Match>
   <Naming>
      <PayloadBased NameField="SubscriberName" />
   </Naming>
   <Metadata>
      <FAS.TestNode>yes</FAS.TestNode>
   </Metadata>
</Region>

感兴趣的区域

WPA 功能