.NET7中带标签的Counter指标10分钟后消失/重置的原因及解决方法
问题:.NET7中System.Diagnostics.Counter标签指标消失重置与ObservableGauge标签添加
一、当前实现代码
1. Meter与Counter创建
// Meter creation private static Meter meter = new Meter("my_library"); // Counter creation private static Counter<int> myCounter= meter.CreateCounter<int>("my_metric_counter", description: "My counter");
2. 事件触发时更新Counter
// When event A happens myCounter.Add(1, KeyValuePair.Create<string, object>("tag_key", "A"));
// When event B happens myCounter.Add(1, KeyValuePair.Create<string, object>("tag_key", "B"));
3. Prometheus指标服务器配置
applicationBuilder.UseMetricServer();
二、问题现象
- 初始状态Prometheus可正常抓取到指标:
my_library_my_metric_counter{tag_key="tag value A"} 10 my_library_my_metric_counter{tag_key="tag value B"} 20
- 当某标签(如tag value B)超过10分钟未更新时,该标签的指标会从抓取结果中消失;再次更新该标签时,指标重现但数值重置为1:
my_library_my_metric_counter{tag_key="tag value A"} 200 my_library_my_metric_counter{tag_key="tag value B"} 1
三、解决方案
1. 解决Counter标签指标消失重置问题
这个行为是System.Diagnostics.Metrics的默认过期机制导致的:默认带有标签的指标维度10分钟无活动会被自动移除,再次更新时会重新创建维度,数值从零开始累加。
有两种解决方式:
方式一:禁用或延长维度过期时间
创建Meter时通过MeterOptions自定义过期时间,比如设置为无限期:private static Meter meter = new Meter(new MeterOptions("my_library") { ExpirationTimeout = Timeout.InfiniteTimeSpan // 禁用自动过期 // 也可以设置更长的有效时间,比如TimeSpan.FromHours(24) });这样标签维度不会因无活动被清理,数值也不会重置。
方式二:定期发送“心跳”更新
如果不想禁用过期机制,可给需要保留的标签维度定期执行Add(0)操作,维持其活跃状态:// 示例:每5分钟给标签A、B发送一次心跳 _ = Task.Run(async () => { while (true) { myCounter.Add(0, KeyValuePair.Create<string, object>("tag_key", "A")); myCounter.Add(0, KeyValuePair.Create<string, object>("tag_key", "B")); await Task.Delay(TimeSpan.FromMinutes(5)); } });
2. 为ObservableGauge添加标签的方法
ObservableGauge通过返回Measurement<T>集合来实现带标签的指标,具体代码示例:
private static ObservableGauge<int> myGauge; static YourClass() { var meter = new Meter("my_library"); // 创建带标签的ObservableGauge myGauge = meter.CreateObservableGauge<int>("my_gauge", () => { // 返回所有带标签的指标测量值 return new[] { new Measurement<int>(GetTagAValue(), KeyValuePair.Create<string, object>("tag_key", "A")), new Measurement<int>(GetTagBValue(), KeyValuePair.Create<string, object>("tag_key", "B")) }; }, description: "My observable gauge with tags"); } // 获取标签A对应的指标值 private static int GetTagAValue() { // 替换为你的实际业务逻辑 return 100; } // 获取标签B对应的指标值 private static int GetTagBValue() { // 替换为你的实际业务逻辑 return 200; }
每次Prometheus抓取时,会执行委托逻辑生成所有带标签的指标值,因此不会出现指标消失的问题。
内容的提问来源于stack exchange,提问作者David Welch
相关产品推荐
相关产品推荐

