You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET:如何用TraceEvent解析直方图指标并实现dotnet-counters输出

使用DiagnosticsClient收集.NET应用指标的问题

我正在用DiagnosticsClient从一个.NET应用向另一个应用收集指标,代码如下:

var providers = new List<EventPipeProvider>()
{
    new EventPipeProvider("System.Diagnostics.Metrics", EventLevel.Verbose, keywords: -1, arguments: new Dictionary<string, string>
    {
        ["Metrics"] = "SomeApi",
        ["Metrics"] = "MyApp",
    }),
};

client = new DiagnosticsClient(pid);
session = client.StartEventPipeSession(providers, requestRundown: false);

source = new EventPipeEventSource(session.EventStream);

source.Dynamic.All += (TraceEvent obj) =>
{
    if (obj.PayloadNames.Length < 7) return;

    var n = obj.PayloadValue(3) as string; 
    var v = obj.PayloadValue(6) as string; 

    //[0]: "sessionId"
    //[1]: "meterName"
    //[2]: "meterVersion"
    //[3]: "instrumentName"
    //[4]: "unit"
    //[5]: "tags"
    //[6]: "lastValue"
};

我发现payload索引6对应Counter这类普通指标的lastValue,但Histogram或Observable Gauge类型的指标无法获取对应值。我希望实现与dotnet-counters一致的指标输出效果(如图所示:dotnet-counters输出示例)。

补充说明:我的代码基于微软官方文档和一篇技术博客的内容。


解决方案

不同类型的指标在EventPipe事件中的Payload结构存在差异,不能通过硬编码索引的方式统一取值。要实现和dotnet-counters一致的输出效果,需按指标类型区分解析:

  1. 区分事件类型
    每个Metrics事件的EventName对应不同指标类型:Counter对应Counter事件、Histogram对应Histogram、Observable Gauge对应ObservableGauge,可通过obj.EventName判断。

  2. 按类型解析Payload
    直接通过Payload字段名取值(比索引更可靠),针对不同指标类型提取对应数据:

    • Counter/UpDownCounter:提取lastValue字段
    • Histogram:提取sum、count、min、max以及buckets分位数数据
    • Observable Gauge:提取value字段

修改后的核心代码示例:

source.Dynamic.All += (TraceEvent obj) =>
{
    var instrumentName = obj.PayloadValue("instrumentName") as string;
    var meterName = obj.PayloadValue("meterName") as string;

    switch (obj.EventName)
    {
        case "Counter":
        case "UpDownCounter":
            var lastValue = obj.PayloadValue("lastValue");
            Console.WriteLine($"{meterName} | {instrumentName}: {lastValue}");
            break;
        case "Histogram":
            var sum = obj.PayloadValue("sum");
            var count = obj.PayloadValue("count");
            var min = obj.PayloadValue("min");
            var max = obj.PayloadValue("max");
            Console.WriteLine($"{meterName} | {instrumentName}: Sum={sum}, Count={count}, Min={min}, Max={max}");
            // 可选:遍历输出buckets中的分位数数据
            break;
        case "ObservableGauge":
            var gaugeValue = obj.PayloadValue("value");
            Console.WriteLine($"{meterName} | {instrumentName}: {gaugeValue}");
            break;
    }
};
  1. 修复Provider配置问题
    你当前的字典参数中重复设置了Metrics键,字典键唯一会导致只有最后一个MyApp生效。若要同时收集多个目标的指标,需用逗号分隔:
new EventPipeProvider("System.Diagnostics.Metrics", EventLevel.Verbose, keywords: -1, arguments: new Dictionary<string, string>
{
    ["Metrics"] = "SomeApi,MyApp",
}),

内容的提问来源于stack exchange,提问作者Boppity Bop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:53:16