定义事件数据模板
提供程序使用数据模板来定义事件中包含的特定于事件的数据,并定义 ETW 跟踪会话在启用提供程序时可以传递给提供程序的筛选器数据。 如果事件不包含特定于事件的数据,则不会定义模板。 若要定义模板,请使用 template 元素。 模板包含提供程序随事件包含的每个数据段的数据项。 可以指定整型类型、字符串、数组和结构。 必须按照模板中定义数据项的顺序写入事件数据。
还可以在模板中包含一个 XML 片段,使用者应使用该片段来确定如何呈现事件数据。 如果不包含片段,使用者应按照数据项在模板中定义的顺序呈现事件数据。
定义模板时,必须为其指定一个模板标识符,用于在事件定义中引用模板。 模板中的每个数据项都必须为输入类型列表指定名称和输入数据类型 (,请参阅 InputType 复杂类型) 的“备注”部分。 如果输入数据类型可以采用多种格式呈现,则应指定指示使用者如何呈现数据项的输出数据类型。 例如,UInt32 输入数据类型可以呈现为无符号整数、线程标识符、IPv4 地址和 Win32 错误代码等。 如果未指定输出数据类型,使用者应使用输入类型的默认输出类型来呈现数据项。
若要指定数组,请在数据项上包括 count 属性,并将其设置为数组中的元素数。 数组可以是可变大小的数组或固定大小的数组。 如果数组是固定大小的数组,请将 count 设置为数组的大小。 例如,如果整数数组的固定大小为 10,请将 count 设置为 10。 写入数组时,必须写入 40 字节的数据。
如果数组是可变大小的数组,请将 count 设置为包含数组大小的数据项的名称。 如果数组包含指针,则指针的地址将写入为事件数据,而不是指针指向的数据。
如果数据项是二进制 Blob,则必须指定 length 属性。 还可以为固定长度字符串指定 length 属性。
如果数据项表示枚举值,并且你希望使用者打印值而不是值本身的字符串,则指定 map 属性。
如果在模板中包含结构,则应单独编写结构的成员,而不是编写结构,除非可以保证 8 字节边界对齐。
应仔细考虑事件中包含的信息,尤其是在事件写入全局通道时。 一般情况下,不应在事件中包含私人信息。 这包括纯文本密码和个人用户信息。 此外,用户运行的程序、用户访问的 URL 以及与计算机上的用户活动相关的其他信息应被视为私有。
如果必须在事件中记录 URL 和用户名,请不要将它们写入 Windows 通道 (系统和应用程序) ,因为这些通道可由所有经过身份验证的用户读取。 相反,请将它们写入你自己的操作或分析频道。 设置对这些通道的访问权限,以仅允许管理员读取事件。 你可能需要提供适当的披露,以通知用户私人信息提供给管理员的事实。
以下示例演示如何定义模板。 必须指定在事件定义或筛选器定义中引用的模板 的 tid 属性。
<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 name="Microsoft-Windows-SampleProvider"
guid="{1db28f2e-8f80-4027-8c5a-a11f7f10f62d}"
symbol="PROVIDER_GUID"
resourceFileName="<path to the exe or dll that contains the metadata resources>"
messageFileName="<path to the exe or dll that contains the string resources>"
message="$(string.Provider.Name)">
. . .
<maps>
<valueMap name="TransferType">
<map value="1" message="$(string.TransferType.Download)"/>
<map value="2" message="$(string.TransferType.Upload)"/>
<map value="3" message="$(string.TransferType.UploadReply)"/>
</valueMap>
<bitMap name="DaysOfTheWeek">
<map value="0x1" message="$(string.DaysOfTheWeek.Sunday)"/>
<map value="0x2" message="$(string.DaysOfTheWeek.Monday)"/>
<map value="0x4" message="$(string.DaysOfTheWeek.Tuesday)"/>
<map value="0x8" message="$(string.DaysOfTheWeek.Wednesday)"/>
<map value="0x10" message="$(string.DaysOfTheWeek.Thursday)"/>
<map value="0x20" message="$(string.DaysOfTheWeek.Friday)"/>
<map value="0x40" message="$(string.DaysOfTheWeek.Saturday)"/>
</bitMap>
</maps>
<templates>
<template tid="t2">
<data name="TransferName" inType="win:UnicodeString"/>
<data name="Day" inType="win:UInt32" map="DaysOfTheWeek"/>
<data name="Transfer" inType="win:UInt32" map="TransferType"/>
</template>
<template tid="t3">
<data name="TransferName" inType="win:UnicodeString"/>
<data name="ErrorCode" inType="win:Int32" outType="win:HResult"/>
<data name="FilesCount" inType="win:UInt16" />
<data name="Files" inType="win:UnicodeString" count="FilesCount"/>
<data name="BufferSize" inType="win:UInt32" />
<data name="Buffer" inType="win:Binary" length="BufferSize"/>
<data name="Certificate" inType="win:Binary" length="11" />
<data name="IsLocal" inType="win:Boolean" />
<data name="Path" inType="win:UnicodeString" />
<data name="ValuesCount" inType="win:UInt16" />
<struct name="Values" count="ValuesCount" >
<data name="Value" inType="win:UInt16" />
<data name="Name" inType="win:UnicodeString" />
</struct>
</template>
</templates>
. . .
</provider>
</events>
</instrumentation>
<localization>
<resources culture="en-US">
<stringTable>
<string id="Provider.Name" value="Sample Provider"/>
<string id="TransferType.Download" value="Download"/>
<string id="TransferType.Upload" value="Upload"/>
<string id="TransferType.UploadReply" value="Upload-reply"/>
<string id="DaysOfTheWeek.Sunday" value="Sunday"/>
<string id="DaysOfTheWeek.Monday" value="Monday"/>
<string id="DaysOfTheWeek.Tuesday" value="Tuesday"/>
<string id="DaysOfTheWeek.Wednesday" value="Wednesday"/>
<string id="DaysOfTheWeek.Thursday" value="Thursday"/>
<string id="DaysOfTheWeek.Friday" value="Friday"/>
<string id="DaysOfTheWeek.Saturday" value="Saturday"/>
</stringTable>
</resources>
</localization>
</instrumentationManifest>