如何使用DiagnosticsClient获取可观测仪表(Gauge)值?
问题1:使用DiagnosticsClient获取可观测仪表(Gauge)的值
核心逻辑
DiagnosticsClient通过订阅目标进程的EventCounter事件流获取Gauge指标,和dotnet-counters底层逻辑一致。Gauge属于EventCounter的一种,会以定期推送的形式输出瞬时值。
实现步骤与代码示例
- 获取目标进程PID:可通过
Process.GetProcessesByName("你的进程名")或命令行工具定位。 - 初始化客户端并创建EventPipe会话:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Tracing; using Microsoft.Diagnostics.NETCore.Client; class GaugeMonitor { static void Main(string[] args) { int targetPid = 12345; // 替换为目标进程PID var client = new DiagnosticsClient(targetPid); // 配置会话,订阅目标Provider的EventCounters事件 var providers = new List<EventPipeProvider> { new EventPipeProvider( "System.Runtime", // 替换为Gauge所属的Provider名称 EventLevel.Informational, (long)EventKeywords.None, new Dictionary<string, string> { ["EventCounterIntervalSec"] = "1" // 设置每秒推送一次指标 } ) }; // 启动会话并处理事件 using var session = client.StartEventPipeSession(providers); var source = new EventPipeEventSource(session.EventStream); // 筛选并解析Gauge值 source.Dynamic.All += (TraceEvent obj) => { if (obj.EventName == "EventCounters") { var payload = obj.PayloadValueCollection; string counterName = payload["Name"].ToString(); string counterType = payload["CounterType"].ToString(); if (counterType == "Gauge" && counterName == "你的Gauge名称") { double gaugeValue = double.Parse(payload["Mean"].ToString()); Console.WriteLine($"当前Gauge值: {gaugeValue}"); } } }; try { source.Process(); } catch (Exception ex) { Console.WriteLine($"会话终止: {ex.Message}"); } } }
关键说明
- 替换
System.Runtime为Gauge所属的自定义EventSource名称(若使用默认Runtime指标则无需修改)。 EventCounterIntervalSec控制指标推送频率,对应dotnet-counters的--refresh-interval参数。- Gauge的瞬时值存储在
Mean字段中,这是EventCounter对Gauge类型的标准承载方式。
问题2:.NET中使用TraceEvent解析直方图指标
直方图指标同样通过EventCounter推送,TraceEvent可直接解析EventCounters事件的Payload获取桶边界与计数:
实现代码示例
source.Dynamic.All += (TraceEvent obj) => { if (obj.EventName == "EventCounters") { var payload = obj.PayloadValueCollection; string counterName = payload["Name"].ToString(); string counterType = payload["CounterType"].ToString(); if (counterType == "Histogram" && counterName == "你的直方图名称") { // 提取桶边界与对应计数 string[] bucketBoundaries = ((string)payload["HistogramBuckets"]).Split(','); string[] bucketCounts = ((string)payload["HistogramBucketCounts"]).Split(','); Console.WriteLine("直方图数据:"); for (int i = 0; i < bucketBoundaries.Length; i++) { Console.WriteLine($"≤ {bucketBoundaries[i]}: {bucketCounts[i]} 次"); } } } };
关键说明
- 直方图的桶边界存储在
HistogramBuckets字段,对应计数在HistogramBucketCounts字段,两者用逗号分隔、一一对应。 - 若使用自定义EventSource输出直方图,需确认字段命名是否与标准一致,必要时调整解析逻辑。
内容的提问来源于stack exchange,提问作者Boppity Bop
相关产品推荐
相关产品推荐

