Stefan Holm Olsen

Remember to flush Application Insights on shutdown!

If you use Azure Application Insights to collect logging and performance metrics for your websites, which I strongly recommend, then you may want to ensure it supports graceful website shutdown.

The case in question

As it turns out, the Application Insights client keeps a buffer of data to send to Azure, instead of sending it continuously. Unless the buffer is filled up, the buffer is only flushed at certain intervals (30 seconds by default).

If a server shuts down the site before the telemetry buffer is flushed, then we risk losing important log data if they were logged between the last flush and the shutdown.

Such a shutdown typically happens when:

  1. A cloud web app receives less load and decides to shut down one or more servers.
  2. A webserver is restarted (manually or because of a deployment) or shut down.

To give the Application Insights client a chance to flush that remaining log data, I hereby present a tiny fix to Episerver developers.

The following class is an initialization module that will flush the buffer on shutdown.

using System.Threading;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using Microsoft.ApplicationInsights;

namespace MyWebsite.Infrastructure
{
    [InitializableModule(UninitializeOnShutdown = true)]
    public class ApplicationInsightsInitialization : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {
        }

        public void Uninitialize(InitializationEngine context)
        {
            var telemetryClient = new TelemetryClient();
            if (!telemetryClient.IsEnabled())
            {
                // No need to flush and wait, if telemetry is not even enabled.
                return;
            }

            // Initiate flush and give it some time to finish.
            telemetryClient.Flush();
            Thread.Sleep(5000);
        }
    }
}

Final notes

The above fix only works when the shutdown is graceful. The code will not be called if the site is shut down because:

  1. The webserver (IIS) is forced to shut down or reset. Or the worker process is killed.
  2. The site experienced a critical error that crashed the site.
  3. The server is killed or loses power.

Also, be aware that auto-flush will be enabled by on default the Application Insights’ trace listener (which is used in Episerver DXP). This means that it will flush the buffer on each write to the trace diagnostics listener.

This is not only inefficient, but it also means that the buffer may have already been flushed when the above fix is called on shutdown; or it might not. Therefore, a fix like this is still a nice safeguard.

With the initialization module in place, the trace listener auto-flush can even be disabled (in web.config), to fully utilize Application Insight’s telemetry buffer. This is particularly useful if the site is logging a lot, because it greatly limits the network traffic that comes with very frequent buffer flushing.

To turn off trace listener auto-flush, apply the following entries to your web.config file.

<configuration>
  <system.diagnostics>
    <!-- Change autoflush to false, to let the buffer fill before flushing.-->
    <trace autoflush="false" indentsize="0">
      <listeners>
        <add name="ApplicationInsightsListener" type="Microsoft.ApplicationInsights.TraceListener.ApplicationInsightsTraceListener, Microsoft.ApplicationInsights.TraceListener" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>