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

.NET 4.8 Windows Service配置Application Insights无数据排查

.NET 4.8 Windows Service 无法上报Application Insights遥测数据的排查与解决

问题描述

基于.NET 4.8的遗留Windows Service项目,配置Application Insights后无法在Azure平台看到TrackException、TrackTrace等遥测数据,已确认Instrumentation Key和连接字符串正确,尝试默认applicationinsight.config配置也无效。项目每分钟运行定时任务,期望捕获异常并发送日志,但数据始终无法上报。

相关代码如下:

Main方法

static void Main(string[] args)
{
    var theService = new JobManagerService();
    theService.Start();
}

JobManagerService类

internal class JobManagerService
{
    private readonly List<JobManager> _jobs = new List<JobManager>();
    private TelemetryClient _tc;

    public JobManagerService()
    {
        InitializeSomething();
    }

    public void Start()
    {
        var config = TelemetryConfiguration.CreateDefault();
        config.InstrumentationKey = ConfigurationManager.AppSettings["JobManagerInstrumentationKey"]; // 已废弃
        config.ConnectionString = $"InstrumentationKey={ConfigurationManager.AppSettings["JobManagerInstrumentationKey"]};IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/";
        config.TelemetryInitializers.Add(new AppInsightsJobManagerTelemetryInitializer());

        _tc = new TelemetryClient(config);
        _tc.TrackTrace($"Starting ApplicationInsights {nameof(TelemetryClient)} for {nameof(JobManagerService)}");
        AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionEventRaised;

        _jobs.Add(new JobManager(interval, job, App_Online, _tc));
        _tc.TrackTrace($"Job {job.Name} Initialized with interval {interval} ms");
        _tc.Flush();
    }

    private void UnhandledExceptionEventRaised(object sender, UnhandledExceptionEventArgs e)
    {
        _tc.TrackException((Exception)e.ExceptionObject);
    }

    private class AppInsightsJobManagerTelemetryInitializer
    {
        public void Initialize(ITelemetry telemetry)
        {
            telemetry.Context.Properties["SystemGuid"] = Config.SystemConfiguration.SystemGuid.ToString();
            telemetry.Context.Properties["SystemName"] = Config.SystemConfiguration.SystemName.ToString();
            telemetry.Context.Properties["SystemType"] = Config.SystemConfiguration.SystemType.ToString();
        }
    }
}

JobManager类

internal class JobManager
{
    private readonly IJob _job;
    private readonly Timer _timer = new Timer();
    private readonly TelemetryClient _telemetryClient;

    public JobManager(int intInterval, IJob objJob, TelemetryClient telemetryClient)
    {
        if (intInterval > 60000) throw new ArgumentException("Interval cannot exceed 1 minute");
        _telemetryClient = telemetryClient;

        _job = objJob;

        _timer.Interval = intInterval;
        _timer.Enabled = true;
        _timer.Elapsed += mObjTimer_Elapsed;
    }

    private void mObjTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            _timer.Enabled = false;
            var _mObjJobCollection = new JobProviderService().ListByService(_job.Name);

            foreach (var objJob in _mObjJobCollection)
            {
                var objRunner = new JobRunner(objJob, _job);
                objRunner.Run();
            }
        }
        catch (Exception ex)
        {
            _telemetryClient.TrackException(ex);
        }
        finally
        {
            _telemetryClient.TrackDependency("Windows Service", _job.Name, _job.Name);
        }
    }
}

关键问题与修复步骤

1. 遥测初始化器未实现ITelemetryInitializer接口

你的AppInsightsJobManagerTelemetryInitializer类没有实现Application Insights要求的ITelemetryInitializer接口,导致初始化逻辑完全不会被执行,甚至可能干扰遥测数据的正常发送。

修复代码:

private class AppInsightsJobManagerTelemetryInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        telemetry.Context.Properties["SystemGuid"] = Config.SystemConfiguration.SystemGuid.ToString();
        telemetry.Context.Properties["SystemName"] = Config.SystemConfiguration.SystemName.ToString();
        telemetry.Context.Properties["SystemType"] = Config.SystemConfiguration.SystemType.ToString();
    }
}

2. Flush调用后未等待发送完成

TelemetryClient.Flush()是异步操作,直接调用后如果没有等待,遥测数据可能还没完成发送就继续执行后续逻辑,导致数据丢失。尤其是在服务启动、异常捕获、服务停止的场景下,必须等待足够时间让SDK完成数据上传。

修复示例:

  • 在Start方法末尾:
_tc.Flush();
System.Threading.Thread.Sleep(5000); // 等待5秒,可根据网络情况调整
  • 在未处理异常事件中:
private void UnhandledExceptionEventRaised(object sender, UnhandledExceptionEventArgs e)
{
    _tc.TrackException((Exception)e.ExceptionObject);
    _tc.Flush();
    System.Threading.Thread.Sleep(5000);
}
  • 新增服务停止逻辑(需在服务的Stop方法中调用):
public void Stop()
{
    _tc.TrackTrace("JobManagerService is stopping");
    _jobs.ForEach(job => /* 清理定时任务资源 */);
    _tc.Flush();
    System.Threading.Thread.Sleep(5000);
}

3. 配置优先级与读取方式问题

同时设置InstrumentationKey和ConnectionString时,ConnectionString优先级更高,但硬编码拼接连接字符串容易出错。建议直接从配置文件读取完整的连接字符串,避免手动拼接。

步骤:

  1. 在App.config中添加完整连接字符串:
<appSettings>
    <add key="JobManagerConnectionString" value="InstrumentationKey=YOUR_KEY_HERE;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/" />
</appSettings>
  1. 修改Start方法中的配置代码:
var config = TelemetryConfiguration.CreateDefault();
// 移除InstrumentationKey设置,直接使用连接字符串
config.ConnectionString = ConfigurationManager.AppSettings["JobManagerConnectionString"];
config.TelemetryInitializers.Add(new AppInsightsJobManagerTelemetryInitializer());

4. 定时任务遗漏Timer重新启用

原JobManager的mObjTimer_Elapsed方法中,finally块未重新启用Timer,导致任务只执行一次就停止,自然也不会产生后续的遥测数据。

修复代码:

finally
{
    _telemetryClient.TrackDependency("Windows Service", _job.Name, _job.Name);
    _timer.Enabled = true; // 重新启用定时任务
}

5. 确认SDK版本与依赖包

确保安装了兼容.NET 4.8的最新Application Insights SDK包,推荐安装Microsoft.ApplicationInsights.WindowsServer(包含针对Windows服务的优化功能),而非仅基础包。

通过NuGet安装:

Install-Package Microsoft.ApplicationInsights.WindowsServer

6. 验证遥测发送状态

可以启用SDK的调试日志,查看是否有发送失败的错误信息:
在App.config中添加:

<system.diagnostics>
    <trace autoflush="true">
        <listeners>
            <add name="aiListener" type="Microsoft.ApplicationInsights.TraceListener.ApplicationInsightsTraceListener, Microsoft.ApplicationInsights.TraceListener" />
        </listeners>
    </trace>
</system.diagnostics>

本地调试时,可查看输出窗口的日志,排查是否有认证错误、网络问题等。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 23:27:04