首页 > 解决方案 > 使用 TraceProcessor 解析 CLR 事件

问题描述

我已按照https://docs.microsoft.com/en-us/windows/apps/trace-processing/extensibility上的指导来掌握 .NET 运行时事件。当我得到一个带有未解析数据的 EventContext 实例时,我没有方便的方法来进一步解析事情吗?

理想情况下,应该有一个基于清单的事件的解析器生成器,就像 TraceEvent 的情况一样。就像是

TraceProcessorGen -generateEvents c:\Windows\Microsoft.NET\Framework\v4.0.30319\CLR-ETW.man

会有很大帮助。我不倾向于为数十个事件手动编写具有数百个硬编码偏移量的解析代码。

class ClrDataSource : IFilteredEventConsumer
{
    public IReadOnlyList<Guid> ProviderIds { get; } = new Guid[] { new Guid("e13c0d23-ccbc-4e12-931b-d9cc2eee27e4") };

    public int Count { get; private set; }

    public void Process(EventContext eventContext)
    {
        ReadOnlySpan<byte> data = eventContext.Event.Data;
        // What do do next? 
    }
}

Vance Morrison 的 TraceEvent 提供了一种简单的方法来探索基于清单的事件,其中 Payload 和 PayloadNames 已经根据它们的清单进行了预解析。这不是很有效,但对于许多情况和探索性研究非常有帮助。

标签: etw.net-traceprocessing

解决方案


(我是 Microsoft 的一名开发人员,从事 TraceProcessor 项目。)

IFilteredEventConsumer 是一种在跟踪中获取未解析事件的方法,而且我们确实没有添加对使用清单文件来简化解析的支持。

但是,该提供程序的解析事件应该在IGenericEventDataSource中可用,如下所示:

using (ITraceProcessor trace = TraceProcessor.Create(tracePath))
{
    Guid[] providerIds = new[] { Guid.Parse("e13c0d23-ccbc-4e12-931b-d9cc2eee27e4") };

    IPendingResult<IGenericEventDataSource> pendingEventsData = trace.UseGenericEvents(providerIds);

    trace.Process();

    IGenericEventDataSource eventData = pendingEventsData.Result;

    foreach (IGenericEvent genericEvent in eventData.Events)
    {
        // Process event here
    }
}

在每个IGenericEvent中,都有一个名为Fields的属性,它可以让您通过整数索引或名称访问事件。


推荐阅读