You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core中如何在应用启动后设置Application Insights连接字符串?

问题

我在多个.NET Core 7项目中使用Application Insights将日志遥测数据发送至Azure,多数项目通过Azure Key Vault避免在应用中存储连接字符串。但我的IoT项目需求特殊:

  • 设备为无人值守类型,不会托管在Azure环境,无法使用Azure Key Vault
  • 采用TPM认证连接Azure IoT Hub,必须先完成Hub连接,才能通过设备孪生属性获取Application Insights的连接字符串,项目本身不存储任何密钥或连接字符串
  • 连接Hub前仅需将日志记录到本地文本文件,无需向Azure发送遥测数据

想明确以下问题:

  1. 是否可以在启动时初始化Application Insights,之后再补充设置连接字符串?
  2. 有没有办法不在启动时初始化服务,等需要的时候再启用?
  3. 如果不在启动时注册服务,而是在业务逻辑中创建TelemetryClient,发送大量日志会不会有性能问题?

附常规场景下的Program.cs代码示例:

// Configure the Azure Key Vault. We action this straight away in order we can use it to get
// the instrumentation key needed for app insights, which we need to setup before configuring
builder.Configuration.AddAzureKeyVault(
        new Uri($"https://{builder.Configuration["AzureKeyVaultConfig:KeyVaultName"]}.vault.azure.net/"),
        new DefaultAzureCredential());

// Create the connection string for App Insights.
var appInsightConnectionString = "InstrumentationKey="
    + builder.Configuration["ApplicationInsights:InstrumentationKey"]
    + ";IngestionEndpoint="
    + builder.Configuration["ApplicationInsights:IngestionEndpoint"];

// ----- Configure Application Insights Telemetry -----
Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions aiOptions = new();
aiOptions.ConnectionString = appInsightConnectionString; // See appInsightConnectionString at the top of the page.
aiOptions.EnableQuickPulseMetricStream = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableQuickPulseMetricStream");
aiOptions.EnableEventCounterCollectionModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableEventCounterCollectionModule");
aiOptions.EnableAppServicesHeartbeatTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAppServicesHeartbeatTelemetryModule");
aiOptions.EnableAzureInstanceMetadataTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAzureInstanceMetadataTelemetryModule");
aiOptions.EnableDependencyTrackingTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableDependencyTrackingTelemetryModule");
aiOptions.EnableEventCounterCollectionModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableEventCounterCollectionModule");
aiOptions.EnableAdaptiveSampling = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAdaptiveSampling");
aiOptions.EnableHeartbeat = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableHeartbeat");
aiOptions.AddAutoCollectedMetricExtractor = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("AddAutoCollectedMetricExtractor");
// Web App Options
aiOptions.EnableRequestTrackingTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableRequestTrackingTelemetryModule");
aiOptions.EnableAuthenticationTrackingJavaScript = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAuthenticationTrackingJavaScript");
aiOptions.EnableDiagnosticsTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableDiagnosticsTelemetryModule");
aiOptions.EnableActiveTelemetryConfigurationSetup = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableActiveTelemetryConfigurationSetup");
// Build the serive with the options from above.
//builder.Services.AddLogging(loggingBuilder => loggingBuilder.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>("", LogLevel.Trace));
builder.Services.AddApplicationInsightsTelemetry(aiOptions);

解决方案1:延迟设置Application Insights连接字符串

可以在启动时先初始化Application Insights但不提供连接字符串,等从IoT Hub获取到连接字符串后,再更新全局配置。具体步骤如下:

1. 启动时初始化AI服务(无连接字符串)

在Program.cs中创建不带连接字符串的配置选项,完成服务注册:

// 初始化AI选项,暂不设置连接字符串
var aiOptions = new Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions();
// 保留需要的其他配置项(如采样规则、模块开关等)
aiOptions.EnableQuickPulseMetricStream = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableQuickPulseMetricStream");
aiOptions.EnableAdaptiveSampling = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAdaptiveSampling");
// ...其他配置项保持不变

// 注册AI服务
builder.Services.AddApplicationInsightsTelemetry(aiOptions);

2. 获取连接字符串后更新全局配置

当从IoT Hub设备孪生拿到Application Insights连接字符串后,通过依赖注入获取全局TelemetryConfiguration实例并更新:

// 假设这是获取到连接字符串后的逻辑
var appInsightsConnStr = "从设备孪生属性中获取的连接字符串";

// 从服务容器获取全局配置实例
var telemetryConfig = app.Services.GetRequiredService<TelemetryConfiguration>();
// 更新连接字符串
telemetryConfig.ConnectionString = appInsightsConnStr;

这种方式复用了全局的TelemetryConfiguration,所有自动收集的遥测数据(如请求、依赖)以及通过DI获取的TelemetryClient都会自动使用新的连接字符串,无需重新创建实例,性能与常规场景一致。


解决方案2:延迟注册Application Insights服务

如果不想在启动时就初始化AI服务,可以先仅配置本地日志,等获取到连接字符串后再完成AI服务的注册。

1. 启动时仅配置本地日志

在Program.cs中只添加本地文件日志,暂不注册AI服务:

builder.Logging.AddFile("logs/{Date}.txt");
// 其他本地日志配置(如日志级别、格式等)

2. 调整启动流程:先获取连接字符串再构建服务

对于无人值守设备,可以调整启动顺序,先完成IoT Hub连接并拿到AI连接字符串,再配置并构建Host:

// 第一步:连接IoT Hub,获取Application Insights连接字符串
var appInsightsConnStr = await GetAppInsightsConnStrFromIoTHubAsync();

// 第二步:配置Host并注册AI服务
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureLogging(logging =>
{
    logging.AddFile("logs/{Date}.txt");
    // 添加AI日志提供器
    logging.AddApplicationInsights(appInsightsConnStr);
});
builder.ConfigureServices(services =>
{
    var aiOptions = new Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions
    {
        ConnectionString = appInsightsConnStr,
        // 其他配置项
        EnableQuickPulseMetricStream = true,
        EnableAdaptiveSampling = true
    };
    services.AddApplicationInsightsTelemetry(aiOptions);
    // 注册其他业务服务
});

var host = builder.Build();
await host.RunAsync();

这种方式的优势是AI服务只有在拿到有效连接字符串后才会初始化,避免了启动时的空配置问题,完全适配无人值守设备的启动逻辑。


关于单独创建TelemetryClient的性能问题

如果不通过DI注册,而是每次创建新的TelemetryClient,确实会产生额外性能开销:每个实例都会创建独立的通道和配置,发送大量日志时会导致连接数增加、资源消耗上升。因此强烈推荐通过DI复用全局的TelemetryConfiguration和TelemetryClient,上述两种解决方案均基于全局实例复用,性能与常规场景一致。


内容的提问来源于stack exchange,提问作者OJB1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:22:45