托管 ETW 提供程序和 15002 错误





5.00/5 (1投票)
托管 ETW 提供程序和 15002 错误
最近我一直在玩 ETW(Windows 事件跟踪)。我的目标之一是编写一个托管提供程序,并在我的应用程序中试用 ETW 基础设施。MSDN 上对所有内容都进行了很好的解释,并且实现起来并不难(尤其是在我的简单情况下)。不幸的是,并非所有事情都进展顺利,在这篇文章中,我将向您展示我遇到的一个问题以及诊断损坏的 ETW 提供程序的一些通用路径。
我的提供程序应该尽可能简单,因此我的清单文件只包含所需的字段
<!--?xml version='1.0' encoding='utf-8' standalone='yes'?-->
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<instrumentationManifest xmlns="http://schemas.microsoft.com/win/2004/08/events">
<instrumentation
xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<events xmlns="http://schemas.microsoft.com/win/2004/08/events">
<provider guid="{369D265E-BE68-422B-A4DD-8778320F4D26}"
name="TestAppChannelProvider"
message="$(string.message.provider)"
symbol="TestAppChannel"
resourceFileName="C:\logs\etw\ApplicationChannelProvider.exe"
messageFileName="C:\logs\etw\ApplicationChannelProvider.exe">
<channels>
<importChannel chid="appchnl" name="Application" />
</channels>
<events>
<event value="101"
message="$(string.message.event101)"
level="win:Informational"
channel="appchnl" />
</events>
</provider>
</events>
</instrumentation>
<localization>
<resources culture="en-US">
<stringTable>
<string id="message.event101" value="Test message" />
<string id="message.provider"
value="Trace for application channel" />
</stringTable>
</resources>
</localization>
</instrumentationManifest>
如您所见,它定义了一个只发出一个事件 (101) 的提供程序,并且此事件被发送到应用程序通道。通过定义这种提供程序,我想看看这个事件将如何在事件查看器中出现(它的来源和 XML 数据是什么)。编译清单、资源和应用程序后
mc -cs ApplicationChannelProvider ApplicationChannel.man
rc ApplicationChannel.rc
csc /win32res:ApplicationChannel.res
/debug+ /out:ApplicationChannelProvider.exe ApplicationChannel.cs Program.cs
我将二进制文件复制到目标文件夹
copy ApplicationChannelProvider.* c:\logs\etw
并安装了提供程序
wevtutil im ApplicationChannel.man
新的提供程序出现在 HKLM\Software\Microsoft\Windows\CurrentVersion\WINEVT 注册表中
一个新密钥也被添加到 HKLM\System\CurrentControlSet\Services\Eventlog\Application 中,该密钥将提供程序定义为应用程序事件日志的事件源
通过与其他应用程序分支中的源进行比较,我们可以看到有一个特殊的密钥:ProviderGuid
,它将此事件源链接到我的提供程序。这意味着 Windows 事件日志记录基础设施能够从我的提供程序中消费事件,并且它应该启用它。但是,在我安装了提供程序并运行应用程序后,我没有在应用程序日志中看到任何新事件。那么这里出了什么问题?
我开始在系统中寻找任何错误痕迹或任何可能对我有帮助的信息。幸运的是,我发现 ETW 基础设施能够记录自己的操作,甚至为此目的提供了不同的通道。在事件查看器窗口中选择“显示分析和调试日志”后,我在 Microsoft-Windows-Eventlog 子文件夹下发现了两个通道
调试通道似乎非常详细,并在事件数据中提供了一些 guid,我猜想这些 guid 仅对 ETW 开发人员有价值。另一方面,分析通道提供了更有意义的一组信息,并且在启用它之后,我找到了我正在寻找的错误事件
详细的 XML 数据
<?xml version="1.0" encoding="UTF-8"?>
<Events>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Eventlog"
Guid="{fc65ddd8-d6ef-4962-83d5-6e5cfe9ce148}" />
<EventID>102</EventID>
<Version>0</Version>
<Level>2</Level>
<Task>101</Task>
<Opcode>0</Opcode>
<Keywords>0x800000000020000</Keywords>
<TimeCreated SystemTime="2012-03-14T06:24:55.730708200Z" />
<EventRecordID>6</EventRecordID>
<Correlation />
<Execution ProcessID="1052" ThreadID="4596"
ProcessorID="0" KernelTime="0" UserTime="0" />
<Channel>Microsoft-Windows-EventLog/Analytic</Channel>
<Computer>Sebastian-HP</Computer>
<Security UserID="S-1-5-19" />
</System>
<UserData>
<EventPublisherMetaDataFailure
xmlns="http://manifests.microsoft.com/win/2004/08/windows/eventlog"
xmlns:auto-ns3="http://schemas.microsoft.com/win/2004/08/events">
<Error Code="15002" />
<EventID>0</EventID>
<PublisherName>TestAppChannelProvider</PublisherName>
<PublisherGuid>{369D265E-BE68-422B-A4DD-8778320F4D26}</PublisherGuid>
<ProcessID>0</ProcessID>
</EventPublisherMetaDataFailure>
</UserData>
</Event>
</Events>
15002 是一个 Windows 错误代码,根据 MSDN,表示“发布者元数据在资源中找不到”。至少我对从哪里开始搜索有了一些线索。不幸的是,关于 Internet 上此错误的资料也不多。最后,我偶然发现了 Naveen 的博客,其中包含 一篇关于编写托管 ETW 提供程序的优秀教程。我按照那里描述的步骤操作,仅将通道更改为应用程序通道,令我惊讶(和欣慰:),新事件出现在应用程序日志中。因此,我开始逐个检查清单的哪个元素在我的情况下丢失了。我发现问题在于缺少一个 template 标签。添加它(空的!)后,事件开始出现在应用程序日志中,并且没有记录错误。所以我的最终清单如下所示(添加的行已突出显示)
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<instrumentationManifest xmlns="http://schemas.microsoft.com/win/2004/08/events">
<instrumentation
xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<events xmlns="http://schemas.microsoft.com/win/2004/08/events">
<provider guid="{369D265E-BE68-422B-A4DD-8778320F4D26}"
name="TestAppChannelProvider"
message="$(string.messageprovider)"
symbol="TestAppChannel"
resourceFileName="C:\logs\etw\ApplicationChannelProvider.exe"
messageFileName="C:\logs\etw\ApplicationChannelProvider.exe">
<channels>
<importChannel chid="appchnl" name="Application" />
</channels>
<templates>
<template tid="t1">
</template>
</templates>
<events>
<event value="101"
message="$(string.messageevent101)"
level="win:Informational"
template="t1"
channel="appchnl" />
</events>
</provider>
</events>
</instrumentation>
<localization>
<resources culture="en-US">
<stringTable>
<string id="messageevent101"
value="Test message" />
<string id="messageprovider"
value="Trace for application channel" />
</stringTable>
</resources>
</localization>
</instrumentationManifest>
您可以从 我的博客示例页面 下载清单和应用程序。
作为一般结论,如果您在使用 ETW 时遇到任何问题,请检查 Microsoft-Windows-Eventlog/分析通道(有时也可能检查调试),并尝试从 MSDN 错误描述 中推断原因,或在 Internet 上搜索。并且记住在您的托管提供程序中为您的事件添加模板!:)
归档于:CodeProject, ETW, 追踪