OpenTelemetry下ASP.NET Core自定义Prometheus指标未被采集求助
ASP.NET Core自定义Prometheus指标不显示问题排查
我在ASP.NET Core应用中实现了自定义中间件,用于通过Prometheus记录HTTP请求指标prometheus_demo_request_total。每个HTTP请求都会触发该中间件,且已确认counter.Labels(...).Inc()调用在中间件执行时正常运行,但访问/metrics端点时仅能看到OpenTelemetry的默认指标,自定义指标完全未出现。需要排查问题根源,确保自定义指标能被Prometheus正确采集展示。
Startup.cs 代码
public void ConfigureServices(IServiceCollection services) { ... services.AddOpenTelemetry() .WithMetrics(builder => builder .AddRuntimeInstrumentation() .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddPrometheusExporter()); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, CustomDbContext dbContext, ILogger<RedactableDbContext> logger) { app.UseRequestMiddleware(); ... }
使用的相关NuGet包
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.6.0" /> <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.6.0" /> <PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.6.0-rc.1" /> <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.6.0" /> <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.5.1-beta.1" /> <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.5.1-beta.1" /> <PackageReference Include="OpenTelemetry.Instrumentation.RunTime" Version="1.5.1" /> <PackageReference Include="prometheus-net.AspNetCore" Version="8.2.0" />
核心问题排查点
- 库体系冲突:同时引用
OpenTelemetry.Exporter.Prometheus.AspNetCore和prometheus-net.AspNetCore,两者各自维护独立的指标体系和/metrics端点,OpenTelemetry的exporter无法读取prometheus-net创建的指标,导致自定义指标无法被采集。 - 指标API不兼容:参考的实现大概率是基于prometheus-net原生API创建的Counter,但OpenTelemetry的Prometheus exporter仅识别通过OpenTelemetry API创建的指标,两套API互不兼容。
解决方案
方案一:统一使用OpenTelemetry API创建自定义指标
- 修改ConfigureServices配置:注册自定义Meter
services.AddOpenTelemetry() .WithMetrics(builder => builder .AddRuntimeInstrumentation() .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddPrometheusExporter() .AddMeter("PrometheusDemo")); // 添加自定义Meter名称
- 重构中间件使用OpenTelemetry指标API
public class RequestMiddleware { private readonly RequestDelegate _next; private readonly Counter<long> _requestCounter; public RequestMiddleware(RequestDelegate next, IMeterFactory meterFactory) { _next = next; var meter = meterFactory.Create("PrometheusDemo"); _requestCounter = meter.CreateCounter<long>( "prometheus_demo_request_total", description: "Total number of HTTP requests"); } public async Task InvokeAsync(HttpContext context) { // 可按需添加标签维度,如请求方法、路径 _requestCounter.Add(1, new KeyValuePair<string, object>("method", context.Request.Method), new KeyValuePair<string, object>("endpoint", context.Request.Path)); await _next(context); } }
- 移除冲突包:删除
prometheus-net.AspNetCore的NuGet引用,避免端点冲突。
方案二:统一使用prometheus-net,移除OpenTelemetry Prometheus Exporter
- 修改ConfigureServices配置:注册prometheus-net服务
// 注册prometheus-net指标端点 services.AddMetricServer(); // 注册自定义Counter services.AddSingleton<Counter>(sp => Metrics.CreateCounter("prometheus_demo_request_total", "Total number of HTTP requests"));
- 中间件保持prometheus-net原生用法
public class RequestMiddleware { private readonly RequestDelegate _next; private readonly Counter _requestCounter; public RequestMiddleware(RequestDelegate next, Counter requestCounter) { _next = next; _requestCounter = requestCounter; } public async Task InvokeAsync(HttpContext context) { _requestCounter.Labels(context.Request.Method, context.Request.Path).Inc(); await _next(context); } }
- 移除冲突配置和包:删除
AddPrometheusExporter()配置,以及OpenTelemetry.Exporter.Prometheus.AspNetCore的NuGet引用。
内容的提问来源于stack exchange,提问作者Ammar
相关产品推荐
相关产品推荐

