如何让Application Insights捕获Docker中ASP.NET Core自托管应用里Dapper执行的SQL命令文本
我来帮你搞定这个问题,刚好之前处理过类似的场景——Docker里的ASP.NET Core自托管应用用Dapper,要让Application Insights捕获实际SQL命令文本对吧?首先得说清楚:你提到的Status Monitor完全不用管,那是给IIS托管的应用用的,你的自托管Docker场景根本用不上,别在这上面浪费时间。
下面给你两种可行的方案,从简单到进阶:
方案一:开启Application Insights的SQL命令文本捕获配置
这是最省心的方法,因为Application Insights本身就支持捕获SQL命令文本,只是默认没开启而已。你只需要做两步:
确保引用了最新的Application Insights包
先检查你的项目里有没有引用Microsoft.ApplicationInsights.AspNetCoreNuGet包,尽量用最新稳定版,旧版本可能没有这个配置项。开启SQL命令文本捕获
你可以通过配置文件或者代码来开启:- 用
appsettings.json配置:
在配置文件里的ApplicationInsights节点下添加这个配置:"ApplicationInsights": { "InstrumentationKey": "你的AI密钥", "EnableSqlCommandTextInstrumentation": true } - 用代码配置(Program.cs里):
如果更喜欢用代码控制,在注册Application Insights服务的时候加上这个选项:builder.Services.AddApplicationInsightsTelemetry(options => { options.EnableSqlCommandTextInstrumentation = true; });
- 用
做完这两步,重启你的Docker容器,AI应该就能捕获到实际的SQL命令文本了,而不是只显示服务器和数据库名称。
方案二:用Dapper拦截器手动捕获SQL(如果方案一无效)
有时候因为Dapper的执行方式,默认的AI拦截可能没覆盖到,这时候可以用Dapper的拦截器手动捕获SQL,然后把数据发给Application Insights。
创建一个Dapper拦截器类
这个类要实现IDbCommandInterceptor接口,用来拦截Dapper的SQL执行,然后生成AI的依赖项遥测:using System.Data.Common; using Microsoft.ApplicationInsights; using Microsoft.ApplicationInsights.DataContracts; using System.Data.Entity.Infrastructure.Interception; public class DapperSqlTelemetryInterceptor : IDbCommandInterceptor { private readonly TelemetryClient _telemetryClient; public DapperSqlTelemetryInterceptor(TelemetryClient telemetryClient) { _telemetryClient = telemetryClient; } // 拦截查询类SQL执行 public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { TrackSqlCommand(command); } // 拦截非查询类SQL执行(比如INSERT/UPDATE/DELETE) public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { TrackSqlCommand(command); } // 拦截标量查询执行 public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { TrackSqlCommand(command); } private void TrackSqlCommand(DbCommand command) { // 构建AI的依赖项遥测 var dependencyTelemetry = new DependencyTelemetry { Type = "SQL", Name = command.CommandText, Data = command.CommandText, Target = command.Connection.DataSource, Success = true }; // 发送到Application Insights _telemetryClient.TrackDependency(dependencyTelemetry); } }注册拦截器
在Program.cs里把这个拦截器注册为单例,并且添加到Dapper的拦截链里:// 注册拦截器 builder.Services.AddSingleton<IDbCommandInterceptor, DapperSqlTelemetryInterceptor>(); // 添加到Dapper的拦截系统 var interceptor = builder.Services.BuildServiceProvider().GetRequiredService<IDbCommandInterceptor>(); DbInterception.Add(interceptor);
这样一来,每次Dapper执行SQL的时候,都会被这个拦截器捕获,然后把实际的SQL命令发送到Application Insights里。
额外注意事项
- 敏感数据过滤:捕获SQL命令文本可能会泄露敏感信息(比如密码、用户隐私数据),生产环境一定要记得添加过滤逻辑,把敏感内容替换掉。
- Docker配置验证:确保你的Docker容器里正确设置了Application Insights的InstrumentationKey,可以通过环境变量传递,或者在容器内的配置文件里正确配置,不然AI根本收不到数据。
备注:内容来源于stack exchange,提问作者Yuri Makassiouk

