My .NET Core console application did not write to my Application Insights instance. Well, it did, but only sometimes.
Writing to Application Insights is done asynchronously, usually every 30 seconds or 500 items. This means that you need to give your application some time to flush the cache before closing down. This can be done by configuring a ProcessExit method. This method is called when your Main() function exists.
This is a template where I initialize my TelemetryClient, and then flushes and waits 5 seconds for the cache to flush before the application is exited:
using System; using System.Threading; using Microsoft.ApplicationInsights; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.Extensions.DependencyInjection; namespace MyCode { internal class Program { public static void Main(string[] args) { // Initialize Service Collection var serviceCollection = new ServiceCollection(); ConfigureServices(serviceCollection); // Initialize Service Provider var serviceProvider = serviceCollection.BuildServiceProvider(); // Handling finalizing when process is ended AppDomain.CurrentDomain.ProcessExit += (s, e) => FinalizeApplication(serviceProvider); // Run Application // ... do run ... } private static void FinalizeApplication(ServiceProvider serviceProvider) { // Give TelemetryClient 5 seconds to flush it's content to Application Insights serviceProvider.GetService<TelemetryClient>().Flush(); Thread.Sleep(5000); } private static void ConfigureServices(IServiceCollection serviceCollection) { // Add Application Insights var telemetryConfiguration = TelemetryConfiguration.CreateDefault(); telemetryConfiguration.InstrumentationKey = "add-your-own-key"; var telemetryClient = new TelemetryClient(telemetryConfiguration); serviceCollection.AddSingleton(telemetryClient); } } }
HOW IT WORKS:
My .NET Core 3.1 console application is started by the Main() function. It starts by initializing the service collection. The only thing I do is adding a TelemetryClient to the collection, but this is where you would all all of your services.
The AppDomain.CurrentDomain.ProcessExit is configured to call the “FinalizeApplication” method, and this method will now be called whenever the Main() function exits.
The FinalizeApplication will then flush the TelemetryClient, and waits 5 seconds for the flush to do it’s magic.
Without the 5 second wait, I risk that the Flush is not done flushing before the thread is discontinued, hence the wait. For some reason, 5 seconds seems to be the magic threshold for a flush to do it’s thing.
MORE TO READ:
- What is Application Insights? my Microsoft
- Application Insights API for custom events and metrics by Microsoft
- AppDomain.ProcessExit Event by Microsoft
- Azure ApplicationInsights track custom metrics using the TelemetryClient by briancaos