如何在Prometheus中采集EF Core连接池指标及追踪导出方案
解决方案:EF Core连接池指标接入Prometheus与追踪配置
一、解决连接池指标未显示的问题
1. 调整NuGet依赖包
当前使用的部分OTel包为beta/rc版本,存在兼容性问题,先统一升级到稳定版并补充必要依赖:
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.6.0" /> <PackageReference Include="OpenTelemetry.Instrumentation.SqlClient" Version="1.6.0" /> <!-- 其他OTel包统一调整为1.6.0版本,移除beta版本 --> <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.6.0" /> <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.6.0" /> <PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.8" /> <!-- 升级到最新beta版以兼容 -->
2. 修改Startup.cs配置
EF Core连接池基于ADO.NET SqlClient实现,需添加SqlClient的指标采集,并启用EF Core自身的Meter:
public void ConfigureServices(IServiceCollection services) { services.AddOpenTelemetry() .WithMetrics(builder => builder .AddRuntimeInstrumentation() .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddSqlClientInstrumentation() // 采集SqlClient连接池指标 .AddMeter(httpCountMeter.Name) .AddMeter("Microsoft.EntityFrameworkCore") // 启用EF Core官方Meter .AddPrometheusExporter()) .WithTracing(builder => builder .AddEntityFrameworkCoreInstrumentation(options => { options.SetDbStatementForText = true; options.SetDbStatementForStoredProcedure = true; }) .AddSqlClientInstrumentation()); // 同时添加SqlClient追踪,完善链路 } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 其他中间件... app.UseOpenTelemetryPrometheusScrapingEndpoint(); // 暴露Prometheus抓取端点,默认路径/metrics }
3. 验证指标
启动应用后访问http://your-app-url/metrics,会看到类似以下的连接池指标:
# TYPE sqlclient_connection_pool_size gauge # HELP sqlclient_connection_pool_size Number of connections in the pool sqlclient_connection_pool_size{connection_string="...",pool_id="..."} 10 # TYPE sqlclient_connection_pool_busy gauge # HELP sqlclient_connection_pool_busy Number of busy connections in the pool sqlclient_connection_pool_busy{connection_string="...",pool_id="..."} 5
如果需要将指标名改为你期望的efcore_connection_pool_*格式,可通过Prometheus的relabel_configs重命名,或自定义指标(见下文)。
二、自定义EF Core连接池指标(与期望格式完全匹配)
若默认SqlClient指标不符合需求,可通过自定义Meter实现:
- 定义自定义Meter与指标:
public static class EfCorePoolMetrics { private static readonly Meter _meter = new Meter("EfCore.ConnectionPool", "1.0.0"); public static readonly Gauge<int> PoolSize = _meter.CreateGauge<int>( "efcore_connection_pool_size", "The current size of the EF Core connection pool.", unit: "connections"); public static readonly Gauge<int> BusyConnections = _meter.CreateGauge<int>( "efcore_connection_pool_busy", "Number of connections currently in use.", unit: "connections"); // 其他指标(idle、pending、lifetime)同理定义 }
- 定期更新指标值:
通过EF Core的DbContext或ADO.NET的SqlConnection获取连接池信息,或使用性能计数器:
// 示例:使用性能计数器获取SqlClient连接池数据 var poolSizeCounter = new PerformanceCounter( ".NET Data Provider for SqlServer", "NumberOfConnections", "your-connection-pool-id"); // 定时更新(可通过HostedService实现) EfCorePoolMetrics.PoolSize.Record((int)poolSizeCounter.NextValue(), new KeyValuePair<string, object>("pool", "YourDbContextName"));
三、追踪数据的处理(Prometheus不存储追踪,需用专用后端)
Prometheus是指标系统,不负责存储追踪数据。需将追踪数据导出到Jaeger、Grafana Tempo等专用后端,配置方式如下:
- 添加OTLP导出器配置:
.WithTracing(builder => builder .AddEntityFrameworkCoreInstrumentation(options => { options.SetDbStatementForText = true; options.SetDbStatementForStoredProcedure = true; }) .AddSqlClientInstrumentation() .AddOtlpExporter(options => { options.Endpoint = new Uri("http://your-tracing-backend:4317"); // 替换为你的OTLP端点 options.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc; }));
- 追踪相关指标到Prometheus
OpenTelemetry会自动生成基于追踪的指标(如otel_span_duration、otel_span_total),可直接在Prometheus中查询,用于分析链路性能。
内容的提问来源于stack exchange,提问作者Ammar
相关产品推荐
相关产品推荐

