.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一致的指标输出效果(如图所示:
)。
补充说明:我的代码基于微软官方文档和一篇技术博客的内容。
解决方案
不同类型的指标在EventPipe事件中的Payload结构存在差异,不能通过硬编码索引的方式统一取值。要实现和dotnet-counters一致的输出效果,需按指标类型区分解析:
区分事件类型
每个Metrics事件的EventName对应不同指标类型:Counter对应Counter事件、Histogram对应Histogram、Observable Gauge对应ObservableGauge,可通过obj.EventName判断。按类型解析Payload
直接通过Payload字段名取值(比索引更可靠),针对不同指标类型提取对应数据:- Counter/UpDownCounter:提取
lastValue字段 - Histogram:提取
sum、count、min、max以及buckets分位数数据 - Observable Gauge:提取
value字段
- Counter/UpDownCounter:提取
修改后的核心代码示例:
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; } };
- 修复Provider配置问题
你当前的字典参数中重复设置了Metrics键,字典键唯一会导致只有最后一个MyApp生效。若要同时收集多个目标的指标,需用逗号分隔:
new EventPipeProvider("System.Diagnostics.Metrics", EventLevel.Verbose, keywords: -1, arguments: new Dictionary<string, string> { ["Metrics"] = "SomeApi,MyApp", }),
内容的提问来源于stack exchange,提问作者Boppity Bop
相关产品推荐
相关产品推荐

