如何组织语义记录应用程序块的EventSource?

Pro*_*ofK 9 c# logging etw semantic-logging

语义记录应用程序块(SLAB)对我很有吸引力,我希望在我正在编写的大型复合应用程序中使用它.要使用它,可以编写一个派生自'EventSource'的类,并在类中为每个要记录为事件类型事件的事件和简单字符串包含一个方法.

像我这样的应用程序可能会有数百个此类事件.我可以有一个基于'EventSource'的类只有一个事件,"SomethingHappened",并记录所有内容,在努力和准确度谱的一个极端,我可以为我执行的每个操作都有一个事件.

对于不同的功能区域,使用EventSource衍生产品是一个好主意.该应用程序几乎不了解业务逻辑本身; 这些都是由MEF插件模块提供的,所以我可以拥有bootrapping,安全性,配置更改等的事件源.任何插件模块都可以为它想要记录的任何事件定义事件源.

这是一个很好的策略,还是许多EventSource派生记录器是一个不受欢迎的应用程序功能?

Alo*_*aus 5

从你的问题

...我希望在我写的大型复合应用程序中使用它...

我可以推断出大型是指单个开发人员的背景.在这种情况下,您可以从EventSource派生并将您可能想要的所有事件添加到该类中.为复合应用程序的每个部分创建一个额外的EventSource派生类没有多大意义,因为它会污染已经注册了2K个提供程序的事件源注册数据库.除此之外,如果您需要记住20个需要启用以通过多个层跟踪应用程序逻辑的guid,那么很难为您的应用程序启用日志记录.

折衷方案是在EventSource类中定义一些通用事件

public void WriteViolation(string Subsystem, string Message, string Context)
Run Code Online (Sandbox Code Playgroud)

组件中的每个组件的记录器类

public static class NetworkLogger
{
   public static void Violation(string message)
   {
      GenericSource.Instance.Violation("Network", message, NetworkContext.Current);
   }
}

public static class DatabaseLogger
{
  public static void Violation(string message)
  {
      GenericSource.Instance.Violation("Database", message, DBContext.Current);
  }
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以保持记录器组件的特定性,并且可以在必要时自动将上下文信息添加到通用事件中.另一种方法是在您的应用程序跟踪中使用跟踪方法进入/离开,信息,警告,错误,并且您的EventSource派生类只知道这些事件.为每个跟踪条目添加类型名称+方法名称时,您可以按名称空间进行过滤,并按WPA中的类进行分组,以查看您正在执行的操作.示例显示在.NET 4.0的语义跟踪中.对于大型应用程序,您可以在您的计算机上查看该文件

C:\Windows\Microsoft.NET\Framework\v4.0.30319\CLR-ETW.man
Run Code Online (Sandbox Code Playgroud)

您可以使用Windows SDK中的ecmangen.exe打开它,以获得一个很好的GUI来查看事件的结构..NET只定义了两个事件提供程序.许多事件通过关键字进行分组,以启用.NET的特定方面,例如GC,Loader,Exceptions,....这很重要,因为您可以在启用提供程序特定关键字时通过它,以便仅启用大型提供程序的某些事件.

您还可以查看Microsoft.Windows.ApplicationServer.Applications.45.man,了解Workflow人员如何看待ETW事件.这应该有助于找到自己的方式.由于真正的测试是在客户站点发现生产错误,因此并不是关于如何构建事件.您需要进行多次迭代的概率很高,直到您找到适当的平衡来记录/跟踪相关信息,以帮助您诊断现场故障.