23
  • 我正在使用企业库记录消息。
  • 我希望将其中一些(通常是错误和警告)传递给 Windows 事件系统)。我今天通过 entlib.config 路由这些。

该解决方案有效,到目前为止,效果很好。但是,我有比这个解决方案提供给我的更多的需求。我有多个安装应该记录到不同的日志,但我希望它们的名称在事件查看器中是合乎逻辑和直观的。但是,Windows 事件系统不能有两个名称中的前 8 个字符相同的类别。category-name 可以更长,但只用前 8 个字母来区分。如果发生这种情况,.Net 实际上会输出警告:

只有自定义日志名称的前八个字符是重要的,并且系统上已经有另一个使用给定名称的前八个字符的日志。

目前我不得不求助于神秘的前缀,但我仍然面临着多个安装在重新命名为日志名时相互“冲突”的危险,所以我需要一个更好的解决方案。

但是,在我计算机上的事件查看器中,我可以看到还有日志名的层次结构——这正是我所需要的。微软和思科显然都找到了一种方法来做到这一点:

微软和思科有一个层次结构

但是,如何创建这样的日志层次结构,每个应用程序都可以安装多次?像这样:

CompanyName
  ApplicationName
    Installation1
    Installation2
4

2 回答 2

23

.NET 4 个答案

您所看到的是来自 Windows 事件跟踪 (ETW) 的通道。您可以在注册表中查看相关项目HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT

要使用这些功能,您必须使用新的Windows 事件日志功能,它取代了从 Vista 开始的事件日志API,看起来它主要针对 C/C++ 开发。似乎其中一些是通过System.Diagnostics.Eventing 命名空间公开的。

我发现 ETW 的一个很好的概述是使用 ETW 改进调试和性能调整

好消息是看起来你可以做你想做的事。您将需要创建一个 XML 清单,其中包含提供者信息以及将记录的事件。然后您需要使用清单上的消息编译器(MC.EXE!)来创建标头、资源文件和日志记录类,然后注册提供程序。

如果您下载适用于 Windows 7 和 .NET Framework 4 的 Microsoft Windows SDK,您将在Samples\winbase\Eventing\Provider\Simple\CSharp子目录中找到一个 .NET 示例解决方案,该解决方案将引导您完成所有步骤。

虽然它确实满足您的分层要求并且有点酷,但对于典型的业务线应用程序而言,这在复杂性方面可能有点矫枉过正。此外,消息编译器生成的代码是不安全的代码,因此也可能是负面的。

.NET 4.5 答案

在 .NET 4.5 中,使用 EventSource 类可以更好地支持 ETW。有关介绍,请参阅Windows 高速日志记录:使用 System.Diagnostics.Tracing.EventSource 在 C#/.NET 中 的 ETW。EventSource 现在还支持事件日志。有关演练,请参阅宣布 EventSource NuGet 包 - 写入 Windows 事件日志。基本上,在编译时会为每个 EventSource 生成清单和清单 DLL,并且可以使用 wevtutil.exe 注册它们。通过添加 EventSource 和 Event Log 通道支持,这种方法现在看起来是直接可行的。

最后,请注意那些对 ETW 感兴趣的人,模式和实践团队有一个可以使用 ETW的应用程序块语义日志记录应用程序块。

于 2012-05-10T06:59:13.840 回答
4

提供者必须以“公司-产品-组件”形式命名。为清楚起见,提供者的名称必须包含 2 个“-”符号。可以在此处找到有关这方面的文档。

频道的名称也必须以特定方式写出。同样,MSDN 的文档解释了这一点。您应该将您的频道命名为“公司-产品-组件/类型”的形式。

这是我为您编写的清单片段,以供您使用:

<provider name="Our Company-OurApp-Service"
          guid="{4990f5dc-85a0-4660-9ce0-275e027a02d2}"
          symbol="GUID_PROVIDER"
          resourceFileName="C:\Program Files (x86)\Our Company\OurApp\service.exe"
          messageFileName="C:\Program Files (x86)\Our Company\OurApp\service.exe"
          parameterFileName="C:\Program Files (x86)\Our Company\OurApp\service.exe"
          message="$(string.Provider.Name)">
    <channels>
        <channel chid="c1"
                 name="Our Company-OurApp-Service/Operational"
                 type="Operational"
                 symbol="CHANNEL_1"
                 isolation="Application"
                 enabled="true"/>
    </channels>
    ...

这是我的日志在事件查看器中的显示方式

我们在事件查看器中看到的文件夹层次结构是一种错觉。它实际上只是一个提供者和频道的平面列表,呈现为一个严格的 3 文件夹深度结构。这就是为什么下面的几个文件夹Microsoft/Windows的名称中有破折号而不是进一步嵌套的原因。

于 2013-03-21T23:48:05.213 回答