Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /var/www/rassie.dk/blog.rassie.dk/wp-content/themes/suffusion/functions/media.php on line 666
Using Azure Application Insights to monitor a self-hosted WCF service – Part 1 | Rasmus' Ramblings on IT and other stuff
Dec 032015

Application Insights is a service in Microsoft Azure for Application Performance Monitoring. See more here: https://azure.microsoft.com/en-us/services/application-insights/ .

I’ve previously (1, 2, 3) posted about Application Insights when it was part of Visual Studio Online. It has been moved to the Azure portal, and now has a slightly different API.

It can be used to detect crashes, tracks performance issues and usage of mobile apps, web apps and more.
I’ve used it on a few web sites hosted in IIS or on Azure, and it works great.
For ASP.net web sites, it’s really easy to set up and get going. There the VS2015 integration to it makes it really seamless, and if you can follow a few wizard steps, there is no additional setup needed.

However, if you don’t have a mobile app, an ASP.net site on Azure or local IIS or a J2EE application, then there are no wizards, and no easy setup.

I wanted to monitor some WCF web services. Those aren’t supported out of the box, and particularly these WCF services are self-hosted inside a Windows Service running on some virtual machines at our company’s hosting provider.
Because I have been using Application Insights for a long time, I know what kind of data can be retrieved from applications with it, and how good looking the web pages are. Management likes that they can get fancy graphs of uptime, performance, error rates and such.
So I wanted to add Application Insights (henceforth known as AI) monitoring to this Windows Service.

Luckily, AI is not a black box that can only be thrown at the types of applications Microsoft wants it to support.

These days you can add a few NuGet packages to your application and get a lot of the monitoring automatically. You just need to start up the AI code, and call the tracking API for what you want to monitor. You will then also get automatic dependency tracking, performance counter logging and more.

The solution that I wanted to add AI monitoring to is a Windows Service and a few WCF services in different libraries.

This blog post describes how to add AI tracking and some extra information to the tracked details. Part 2 will describe the WCF message inspector I used to automatically add request tracking for each WCF SOAP operation called.

NuGet packages

I added these NuGet packages to both the service executable project and each of the WCF service library projects:

Microsoft.ApplicationInsights The core API
Microsoft.ApplicationInsights.DependencyCollector Tracks dependency calls (SQL, other web services etc.)
Microsoft.ApplicationInsights.PerfCounterCollector Tracks Windows performance counters
Microsoft.ApplicationInsights.WindowsServer Some Windows information tracking helpers aka. Telemetry Initializers
Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel The underlying code to send the tracking info to Azure
Microsoft.ApplicationInsights.Agent.Intercept For interception of Method calls (used by some of the others packages)
Microsoft.ApplicationInsights.Web Web related tracking helpers

Adding the Microsoft.ApplicationInsights NuGet package will also create a file called ApplicationInsights.config to the project. That file controls a lot of the built-in tracking.

Telemetry Initializers

AI has a lot of “Telemetry Initializers” which add information about e.g. computer hostname, hardware configuration, and more. In a traditional ASP.net web site they also add information from the http headers such as browser user agent, remote IP and more. Another example is the BuildInfoConfigComponentVersionTelemetryInitializer which is in the Microsoft.ApplicationInsights.WindowsServer package. It adds build version information from the BuildInfo.config file if such a file exists.

In an ASP.net web site, AI will also automatically add an Operation ID when ASP.net serves a web request. Since my self hosted WCF services don’t go through that pipeline, I needed to add the Operation ID myself, and make sure that it is the same for all tracking calls that are made while the code serves a single web service call.

To add information to each AI tracking message, simply create an implementation of ITelemetryInitializer. Mine looks like this:

public class ItemCorrelationTelemetryInitializer : ITelemetryInitializer
	public static string CORRELATION_ID = "CORRELATION-ID";
	public static string OPERATION_NAME = "OPERATION-NAME";

	public void Initialize(ITelemetry telemetry)
		if (string.IsNullOrEmpty(telemetry.Context.Operation.Id))
			telemetry.Context.Operation.Id = (string)CallContext.LogicalGetData(CORRELATION_ID);

		if (String.IsNullOrEmpty(telemetry.Context.Operation.Name))
			telemetry.Context.Operation.Name = (string) CallContext.LogicalGetData(OPERATION_NAME);

It just adds an Operation ID and an Operation Name to telemetry.Context.Operation whenever a tracking call is made if the values are not already present. The information is stored in CallContext, and is set elsewhere in a WCF message inspector described in the next part of the blog series.

Telemetry initializers can be added to AI in the ApplicationHosts.config file, but may also be added in code. I elected to do it in code. It’s in the snippet below.

Application Insights runtime configuration

AI needs an Instrumentation Key that is used to identify which AI instance the tracking information should be sent to. Azure identifies your AI instance based on the Instrumentation Key.

The key may be placed in ApplicationInsights.config or it may be set in code. Because I wanted different AI instances for our different environments (dev, test, pre-prod, and production), I chose to set it in code based on the app.config which our build and release system changes based on the target environment.

The code to set instrumentation key is like the code to add a Telemetry Initializer. It needs to be set only once in the application. It looks like this:

TelemetryConfiguration.Active.InstrumentationKey = ConfigurationStore.AppInsightsInstrumentationKey; 
TelemetryConfiguration.Active.TelemetryInitializers.Add(new ItemCorrelationTelemetryInitializer());

The first time the code references TelemetryConfiguration.Active it will look for and load the ApplicationInsights.config file. Thus all the settings that are in that file will be applied at that time.

WCF service instrumentation

The next part of this series will cover adding AI tracking to each WCF service operation using WCF message and operation inspectors.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>