skip to Main Content

I seem to be unable to configure application insight correctly.
Maybe I have missed something very important, or it just can’t be done, the way I intent.
I have a legacy Windows Service project, that I’m trying to get set up, to send some telemetry to app insight, to get some logging of exception, and some messages.

App Insight has been set up for me in Azure, but I don’t get any exceptions, or messages when I configure my C# project. Its just a

Windows Service project

The suedo code looks like this:

(Nevermind the wierd way it is plugged together.. Thats just to give you an idea of what I’m trying to refactor, when I have some metrics)

static void Main(string[] args)
{

    var theService = new JobManagerService();
    theService.Start();
}
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"]; //IS BEING DEPRICATED
            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();
            }
        }
    }
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");
            //If intInterval > 60 * 1000 Then Throw New ArgumentException("Interval cannot exceed 1 minute")
            _telemetryClient = telemetryClient;

            _job = objJob;

            //' Load Jobs
            //_mObjJobCollection = new JobProviderService().ListByService(_job.Name);

            //' Starts the loop that triggers mObjTimer_Elapsed on every "interval"
            _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);
            }
        }
    }

The idea is that some jobs get run every 1 minute, and I want to catch exceptions, and just send some log-messages.

But for some reason I don’t get the TrackException() or TrackTrace() in app insights online
The Instrumenentation key and Connectionstring is correct, which should be enough for app insight to establish a connection, but nothing shows up.
I’ve experimentented with applicationinsight.config file, using a default configuration setup, which doesn’t do anything good either.

ApplicationInsights does break.
It just doesn't send data. Not when I debug locally, or when I push it to production.

What am I missing, or what should be the correct way to configure, and use telemetry?

2

Answers


  1. Chosen as BEST ANSWER

    It seems the problem, was not what I thought it was.

    Configuration as such,was correct, but client side Application Insights was not set up correctly..

    Appplication Insights SDK nuget packages, comes in a variety of installations primarily 'Microsoft.ApplicationInsights.Web' and'Microsoft.ApplicationInsights.WorkerService'

    In my case, the Web package had been installed, which twarted my applicationInsights.config file to a clustered mess.

    Deleting applicationInsights.config file, UNinstall Application Insights nuget package, and re-installing 'Microsoft.ApplicationInsights.WorkerService' made en new default applicationInsights.config file, and data started coming through.

    That took some time to figure out. But hopefully this will help some future reader from my agony.

    This Web/WorkerService distinction was not easy for me to figure out from the documentation. BIG SHOUT OUT TO: Tobias Zimmergren


  2. I can think of at least one scenario that can cause the issue. If an unhandled exception occurs the telemetryClient is not flushed, preventing telemetry from being send before the application is terminated.

    Also, do mind that if you do call Flush() you need to add a little delay since the process is async:

    _tc.Flush();
    Thread.Sleep(2000);
    

    or use FlushAsync:

    await _tc.FlushAsync(CancellationToken.None);
    

    See this issue regarding the need to use Thread.Sleep versus calling FlushAsync.

    Finally, make sure to flush the telemetry on all paths before the application is terminated. Given the code as shown it is hard to tell this is the case, especially given your comment (Nevermind the wierd way it is plugged together.. [..])

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search