如何在运行时修改Application Insights的EnableSqlCommandTextInstrumentation配置?
运行时动态修改Application Insights SQL命令文本追踪配置的方案
问题背景
需要通过可重载配置,在运行中动态设置/覆盖EnableSqlCommandTextInstrumentation的值,从而按需启用Application Insights对SQL命令文本的追踪。但由于Microsoft.ApplicationInsights SDK的ConfigureTelemetryModule采用单例注册,无法直接使用IOptionsSnapshot实现动态更新,需要寻找替代方案。
当前代码(Program.cs)
var builder = WebApplication.CreateBuilder(args); ... var myOptions = new MyOptions(); var configSection = builder.Configuration.GetSection(MyOptions.Name); configSection.Bind(myOptions); builder.Services.Configure<MyOptions>(configSection); builder.Services .AddSingleton<ITelemetryInitializer>(_ => new MyTelemetryInitializer(applicationName)) .ConfigureTelemetryModule<DependencyTrackingTelemetryModule>( (module, _) => { module.EnableSqlCommandTextInstrumentation = myOptions.EnableSqlCommandTextInstrumentation; }) .AddApplicationInsightsTelemetry(configuration);
可行解决方案
方案1:直接获取单例模块实例动态修改属性
因为DependencyTrackingTelemetryModule是以单例形式注册的,你可以在任意需要动态更新的地方(比如接口、后台任务)通过IServiceProvider获取该模块实例,直接修改其属性值。
示例代码:
// 在需要修改的服务/控制器中注入IServiceProvider public class ConfigController : ControllerBase { private readonly IServiceProvider _serviceProvider; private readonly IOptionsMonitor<MyOptions> _optionsMonitor; public ConfigController(IServiceProvider serviceProvider, IOptionsMonitor<MyOptions> optionsMonitor) { _serviceProvider = serviceProvider; _optionsMonitor = optionsMonitor; } [HttpPost("toggle-sql-tracking")] public IActionResult ToggleSqlTracking() { // 获取单例的DependencyTrackingTelemetryModule实例 var module = _serviceProvider.GetRequiredService<DependencyTrackingTelemetryModule>(); // 从最新配置中获取值并更新 var currentOption = _optionsMonitor.CurrentValue.EnableSqlCommandTextInstrumentation; module.EnableSqlCommandTextInstrumentation = !currentOption; return Ok(new { Enabled = module.EnableSqlCommandTextInstrumentation }); } }
方案2:使用IOptionsMonitor监听配置变化自动更新
通过IOptionsMonitor监听MyOptions的配置变化,一旦配置更新,自动同步到DependencyTrackingTelemetryModule的属性上。可以在应用启动时注册监听回调。
修改Program.cs:
var builder = WebApplication.CreateBuilder(args); ... var configSection = builder.Configuration.GetSection(MyOptions.Name); builder.Services.Configure<MyOptions>(configSection); builder.Services .AddSingleton<ITelemetryInitializer>(_ => new MyTelemetryInitializer(applicationName)) .ConfigureTelemetryModule<DependencyTrackingTelemetryModule>( (module, _) => { // 初始设置 var initialOptions = configSection.Get<MyOptions>(); module.EnableSqlCommandTextInstrumentation = initialOptions.EnableSqlCommandTextInstrumentation; }) .AddApplicationInsightsTelemetry(configuration); // 注册配置监听,自动更新模块属性 builder.Services.AddHostedService<ConfigChangeHostedService>(); // 定义HostedService用于监听配置变化 public class ConfigChangeHostedService : IHostedService { private readonly IOptionsMonitor<MyOptions> _optionsMonitor; private readonly DependencyTrackingTelemetryModule _telemetryModule; private IDisposable _listener; public ConfigChangeHostedService(IOptionsMonitor<MyOptions> optionsMonitor, DependencyTrackingTelemetryModule telemetryModule) { _optionsMonitor = optionsMonitor; _telemetryModule = telemetryModule; } public Task StartAsync(CancellationToken cancellationToken) { // 监听配置变化 _listener = _optionsMonitor.OnChange(options => { _telemetryModule.EnableSqlCommandTextInstrumentation = options.EnableSqlCommandTextInstrumentation; }); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _listener?.Dispose(); return Task.CompletedTask; } }
方案3:自定义TelemetryModule继承并重写逻辑
创建自定义的TelemetryModule,继承自DependencyTrackingTelemetryModule,注入IOptionsMonitor<MyOptions>,在模块内部动态读取最新配置值。
示例代码:
// 自定义TelemetryModule public class DynamicDependencyTrackingModule : DependencyTrackingTelemetryModule { private readonly IOptionsMonitor<MyOptions> _optionsMonitor; public DynamicDependencyTrackingModule(IOptionsMonitor<MyOptions> optionsMonitor) { _optionsMonitor = optionsMonitor; // 初始设置 EnableSqlCommandTextInstrumentation = optionsMonitor.CurrentValue.EnableSqlCommandTextInstrumentation; // 监听配置变化 optionsMonitor.OnChange(options => { EnableSqlCommandTextInstrumentation = options.EnableSqlCommandTextInstrumentation; }); } } // 修改Program.cs,替换默认模块 var builder = WebApplication.CreateBuilder(args); ... var configSection = builder.Configuration.GetSection(MyOptions.Name); builder.Services.Configure<MyOptions>(configSection); builder.Services .AddSingleton<ITelemetryInitializer>(_ => new MyTelemetryInitializer(applicationName)) // 移除默认的DependencyTrackingTelemetryModule,添加自定义模块 .RemoveAll<DependencyTrackingTelemetryModule>() .AddSingleton<DependencyTrackingTelemetryModule, DynamicDependencyTrackingModule>() .AddApplicationInsightsTelemetry(configuration);
注意事项
- 所有方案中,
DependencyTrackingTelemetryModule是单例实例,修改属性后会全局生效,影响所有后续的SQL追踪逻辑。 - 若使用配置中心(如Azure App Configuration、Consul等)实现配置重载,确保
MyOptions已正确绑定到可重载的配置源。
内容的提问来源于stack exchange,提问作者Parth Sekar
相关产品推荐
相关产品推荐

