EventSource 入门

本文适用于:✔️ .NET Core 3.1 及更高版本 ✔️ .NET Framework 4.5 及更高版本

本演练演示如何记录新事件 System.Diagnostics.Tracing.EventSource、在跟踪文件中收集事件、查看跟踪以及了解基本 EventSource 概念。

注释

与 EventSource 集成的许多技术使用术语“跟踪”和“跟踪项”,而不是“记录”和“日志”。 此处的含义相同。

记录事件

EventSource 的目标是允许 .NET 开发人员编写如下所示的代码来记录事件:

DemoEventSource.Log.AppStarted("Hello World!", 12);

此代码行具有一个日志记录对象(DemoEventSource.Log)、一个表示要记录的事件的方法,AppStarted以及可选的一些强类型事件参数(HelloWorld!12)。 没有详细级别、事件 ID、消息模板或其他不需要位于调用站点的任何内容。 通过定义派生自 System.Diagnostics.Tracing.EventSource的新类来编写有关事件的所有其他信息。

下面是一个完整的最小示例:

using System.Diagnostics.Tracing;

namespace EventSourceDemo
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            DemoEventSource.Log.AppStarted("Hello World!", 12);
        }
    }

    [EventSource(Name = "Demo")]
    class DemoEventSource : EventSource
    {
        public static DemoEventSource Log { get; } = new DemoEventSource();

        [Event(1)]
        public void AppStarted(string message, int favoriteNumber) => WriteEvent(1, message, favoriteNumber);
    }
}

DemoEventSource 类声明要记录的每种类型的事件的方法。 在这种情况下,AppStarted() 方法定义了名为“AppStarted”的单个事件。 每次代码调用 AppStarted 方法时,如果启用了事件,则会在跟踪中记录另一个 AppStarted 事件。 这是可以通过每个事件捕获的一些数据:

  • 事件名称 - 标识已记录的事件类型的名称。 在这种情况下,事件名称将与方法名称“AppStarted”相同。
  • 事件 ID - 标识所记录的事件类型的数字 ID。 这与名称类似,但可以帮助快速自动处理日志。 AppStarted 事件的 ID 为 1,指定在 EventAttribute 中。
  • 源名称 - 包含事件的 EventSource 的名称。 这用作事件的命名空间。 事件名称和标识符只需在其源范围内是唯一的。 此处的源名为“Demo”,在类定义中 EventSourceAttribute 指定。 源名称通常也称为提供者名称。
  • 参数 - 序列化所有方法参数值。
  • 其他信息 - 事件还可以包含时间戳、线程 ID、处理器 ID、 活动 ID、堆栈跟踪和事件元数据,例如消息模板、详细级别和关键字。

有关创建事件的详细信息和最佳实践,请参阅 对代码进行工具化以创建事件

收集和查看跟踪文件

代码中没有必需的配置,用于描述应启用哪些事件、应发送记录的数据的位置,或存储数据的格式。 如果现在运行应用,则默认情况下不会生成任何跟踪文件。 EventSource 使用 发布-订阅模式,该模式要求订阅者指示应启用的事件,并控制已订阅事件的所有序列化。 EventSource 集成了用于从 Windows 事件跟踪(ETW)EventPipe 订阅的功能(仅限 .NET Core)。 还可以使用 System.Diagnostics.Tracing.EventListener API 创建自定义订阅者。

此演示演示演示了 .NET Core 应用的 EventPipe 示例。 若要了解更多选项,请参阅 “收集和查看事件跟踪”。 EventPipe 是 .NET Core 运行时中内置的开放跨平台跟踪技术,为 .NET 开发人员提供跟踪收集工具和便携式紧凑跟踪格式(*.nettrace 文件)。 dotnet-trace 是一种命令行工具,用于收集 EventPipe 跟踪。

  1. 下载并安装 dotnet-trace
  2. 生成上面的控制台应用。 此演示假定应用名为 EventSourceDemo.exe,并且位于当前目录中。 在命令行上,运行:
>dotnet-trace collect --providers Demo -- EventSourceDemo.exe

这应显示类似于以下内容的输出:

Provider Name                           Keywords            Level               Enabled By
Demo                                    0xFFFFFFFFFFFFFFFF  Verbose(5)          --providers

Launching: EventSourceDemo.exe
Process        : E:\temp\EventSourceDemo\bin\Debug\net6.0\EventSourceDemo.exe
Output File    : E:\temp\EventSourceDemo\bin\Debug\net6.0\EventSourceDemo.exe_20220303_001619.nettrace

[00:00:00:00]   Recording trace 0.00     (B)
Press <Enter> or <Ctrl+C> to exit...

Trace completed.

此命令运行了 EventSourceDemo.exe,启用“演示”EventSource 中的所有事件,并输出跟踪文件 EventSourceDemo.exe_20220303_001619.nettrace。 在 Visual Studio 中打开该文件会显示已记录的事件。

Visual Studio nettrace 文件

在列表视图中,可以看到第一个事件是 Demo/AppStarted 事件。 文本列具有保存的参数,时间戳列显示记录开始后 27 毫秒发生的事件,右侧可以看到调用堆栈。 其他事件在 dotnet-trace 收集的每个跟踪中自动启用,但如果它们分散你的注意力,可以将其忽略并在 UI 的视图中筛选掉。 这些额外事件捕获有关进程和抖动代码的一些信息,这允许 Visual Studio 重新构造事件堆栈跟踪。

详细了解 EventSource