Application Versioning: semantic or automatic?

Looking at @pksorensen’s example of OWIN middleware to monitor server request I noticed this line of code:

rt.Context.Component.Version = "1.0.0";

It will set application version for telemetry items so you can group telemetry by version and understand in which version of application certain exception happened.

Note: Yes, it is confusing name. SDK refers to application as “Component” when in UI it is called “Application”.

This code snippet uses constant string as an application version. My guess is that this version represent semantic version of API call. If you versioned your REST API using urls like this: you’d probably need to change your middleware to read version from api-version query string parameter.

Semantic version is good for certain telemetry reports. For instance you can see how much traffic goes to which version of API to decide when to shut down older version. However semantic version is something you need to code explicitly - there is no generic way to version applications and APIs.

So instead of using semantic version - we suggest to use automatically generated version number. For instance, this article suggest to use Assembly version of your application as application version.

You’ll need to use wildcard in Assembly.cs:

[assembly: AssemblyVersion("1.0.*")]

and use telemetry initializer to initialize application version:

telemetry.Context.Component.Version =

Now all telemetry items will be marked with the version like 1.0.5647.32696, where 5647 and 32696 are some semi-random numbers.

Drawback of this approach is that again, you need to write some code. Furthermore, there is no way to detect which assembly is a “main” assembly of an application. So your telemetry initializer should be application specific.

This brings us to the reason I write this blog post. Visual Studio has a feature that I believe undeservedly is not well known and widely used. It is called build information file or BuildInfo.config.

Turing this feature on is simple. Just add a property to your project file:


This will generate the file bin/$(ProjectName).BuildInfo.config when you compile locally with the commit number and auto-generated build label and BuildInfo.config when you publish your application. For instance, once I enabled continues integration in Visual Studio online this file is placed next to web.config:

<?xml version="1.0" encoding="utf-8"?>
<DeploymentEvent xmlns:xsd="" xmlns:xsi="" xmlns="">
  <SourceControl type="Git">
    <GitSourceControl xmlns="">
      <CommitDateUTC>Thu, 18 Jun 2015 17:07:56 GMT</CommitDateUTC>
      <CommitComment>initial commit</CommitComment>
      <CommitAuthor>Sergey Kanzhelev</CommitAuthor>
  <Build type="TeamBuild">
      <BuildDefinition kind="informative, summary">TestBuildInfoApp_CD</BuildDefinition>
      <BuildLabel kind="label">TestBuildInfoApp_CD_20150618.1</BuildLabel>
      <BuildId kind="id">e6e457a1-debf-4bda-b0c9-61344fd55ae2,vstfs:///Build/Build/37</BuildId>
      <BuildTimestamp kind="informative, summary">Thu, 18 Jun 2015 18:08:19 GMT</BuildTimestamp>
      <Configuration kind="informative">Debug</Configuration>
      <Platform kind="informative">AnyCPU</Platform>

It is great to have this file published with your application as you will always know which version of source code it was built from.

Application Insights Web SDK will install context initializer called BuildInfoConfigComponentVersionContextInitializer that will read this file and mark telemetry items with the application version equal to BuildLabel from the file above. In this example it will be TestBuildInfoApp_CD_20150618.1. Now, looking at your telemetry you can always find the build that produced this binary.

Here are some additional details on how this feature used to work in the old version of Application Insights. From this article you can find that you can use IncludeServerNameInBuildInfo property to enrich BuildInfo.config even more and how to configure copying of this file next to web.config while developing. Do not forget to .gitignore it though…


comments powered by Disqus