如何为OpenTelemetry内置指标添加全局tenant_id属性?
问题
使用OpenTelemetry Metrics采集多租户环境信息,数据最终同步至Prometheus后导入Grafana,期望给所有内置Instrumentation(AspNetCoreInstrumentation、ProcessInstrumentation、RuntimeInstrumentation)生成的指标添加tenant_id标签/属性,但当前配置下,通过UseOpenTelemetryPrometheusScrapingEndpoint暴露的/metrics端点中看不到该属性:
services.AddOpenTelemetry() .WithMetrics(opts => { opts.ConfigureResource(resourceBuilder => { resourceBuilder.AddTelemetrySdk(); resourceBuilder.AddService(serviceName: "tenant_service_config"); resourceBuilder.AddAttributes(new Dictionary<string, object> { ["tenant_id"] = 2 }); }) .AddMeter(meters.MetricName) .AddAspNetCoreInstrumentation() .AddProcessInstrumentation() .AddRuntimeInstrumentation();
手动创建指标并添加标签时,该标签能正常显示在/metrics端点:
_userLoginCounter.Add(1, new KeyValuePair<string, object>("tenant.id", tenantId));
自定义指标可正常同步到Prometheus,仅需解决内置Instrumentation指标的tenant_id标签显示问题。
解决方案
问题根源
通过ConfigureResource添加的属性属于OpenTelemetry的资源元数据,默认情况下Prometheus导出器不会自动将这些资源属性附加到每个指标的标签集合中,因此内置指标不会显示tenant_id。
修复步骤
- 确保项目已安装
OpenTelemetry.Exporter.Prometheus.AspNetCoreNuGet包 - 修改OpenTelemetry Metrics配置,显式启用Prometheus导出器的资源属性包含功能:
services.AddOpenTelemetry() .WithMetrics(opts => { opts.ConfigureResource(resourceBuilder => { resourceBuilder.AddTelemetrySdk(); resourceBuilder.AddService(serviceName: "tenant_service_config"); resourceBuilder.AddAttributes(new Dictionary<string, object> { ["tenant_id"] = 2 }); }) .AddMeter(meters.MetricName) .AddAspNetCoreInstrumentation() .AddProcessInstrumentation() .AddRuntimeInstrumentation() // 开启资源属性作为指标标签 .AddPrometheusExporter(prometheusOpts => { prometheusOpts.IncludeResourceAttributes = true; });
- 确认中间件配置正确(若未添加则补充):
app.UseOpenTelemetryPrometheusScrapingEndpoint();
可选:精细化标签控制
如果需要对资源属性做重命名或筛选,可通过View实现精准控制,比如仅将tenant_id添加到指标标签:
opts.AddView(instrumentName: "*", new MetricStreamConfiguration { TagKeys = new[] { "tenant_id" } });
完成配置后,所有内置Instrumentation生成的指标都会带上tenant_id标签,与自定义指标的标签行为保持一致。
内容的提问来源于stack exchange,提问作者Adri
相关产品推荐
相关产品推荐

