28 people following this project (follow)

Adding Runtime Intelligence Application Analytics for CodePlex with Dotfuscator Community Edition 

Dotfuscator Professional Edition

The Runtime Intelligence Data Visualizer is a WPF application hosted on CodePlex. The usage patterns of the binary releases are not visible to the project developers, however they can receive direct feedback on how the application works and what is being used, but only from the few users who actively report bugs or request features.

With the partnership between CodePlex and PreEmptive Solutions any CodePlex project is able to use Runtime Intelligence to automatically inject usage tracking functionality into any .NET application. This allows CodePlex projects to expose how many times the application is run, which features are being used, and how stable the application is with little effort. By using the latest version of Dotfuscator Software Services Community Edition included in Visual Studio 2010, projects can add Runtime Intelligence instrumentation quickly and easily. The instrumentation is injected into application binaries after compilation and should be performed prior to building a binary release.

The instrumentation of applications can be accomplished by decorating methods within the application source code with custom attributes, by defining injection points using the Dotfuscator user interface (in which case no source code modification is necessary), or by a combination of the two approaches.

Runtime Intelligence instrumentation injection is conceptually similar to aspect weaving in Aspect Orientated Programming. The cross-cutting concern is logging details about method execution and the pointcuts are defined through a combination of custom attribute decoration and/or definition in the Dotfuscator configuration file. The weaving is performed by running the application assembly through Dotfuscator.

Any project hosted on CodePlex is eligible to use the CodePlex identifier to instrument its .NET applications. The total number of application executions will be tracked and reported as part of the project's activity statistics. Detailed information about feature usage will be publicly viewable from the project's CodePlex page.

Adding instrumentation to .NET applications requires few steps. The addition of a privacy option allows users to opt in to having their usage data aggregated requires minimal code modification.

Using the Runtime Intelligence Data Visualizer application as our sample application, let's add the instrumentation.

We will use the custom attributes defined in the PreEmptive.Attributes.dll library included in Visual Studio 2010 to define the majority of our injection points. A few final tweaks to the instrumentation injection will be made with the Dotfuscator user interface. Our first step is to add a reference to %ProgramFiles%\Microsoft Visual Studio 10.0\PreEmptive Solutions\Dotfuscator Community Edition\PreEmptive.Attributes.dll to our project. Dotfuscator will strip out any references to this library during the injection process and there is no need to ship it with the binary release.

We need to add identifying metadata to our assembly. This is necessary as Runtime Intelligence does not require any preconfiguration of the server to track new applications or new features. Everything necessary is included in the application binary.

The first piece of metadata that needs to be added is the identifier of the owner of the Runtime Intelligence subscription. Since CodePlex projects are receiving the benefit of an enterprise level Runtime Intelligence subscription all applications need to use the CodePlex subscription key to identify the application usage data to the Runtime Intelligence Service. To do so, add a PreEmptive.Attributes.Business assembly level attribute with a CompanyID value of "3E35F098-CE43-4F82-9E9D-05C8B1046A45" to the AssemblyInfo file.

Next, each application needs to have its own unique identifier metadata. Generate a new GUID and add a PreEmptive.Attributes.Application assembly level attribute with an ApplicationID value of the GUID to the AssemblyInfo file.

AssemblyInfo

Applications instrumented with Runtime Intelligence require a minimum of two injection points, one to indicate the starting point of the application and one to indicate the application's end point. This is accomplished by decorating methods with a Setup attribute and a Teardown attribute. The method decorated with the Setup attribute should be invoked as a part of the application's start up. Code will be injected into the beginning of the method to start up a Runtime Intelligence in memory queue on a background thread that will periodically send the accumulated usage data ensuring that the runtime performance of the application is as unaffected as possible. The method decorated with the Teardown attribute will have code injected into a Finally block at the end of the method to flush the in memory cache of usage data, send a set of application completed messages, and perform an orderly shutdown of the background thread.

Since our sample application is WPF it makes sense to decorate the Main method with both the Setup and Teardown attributes as this method encapsulates the entire execution of the application.

There are many parameters supported by the Setup attribute; most of them are not available in the free version of Dotfuscator but are included in the commercial version. There is one parameter that is required when instrumenting a CodePlex project with the free version of Dotfuscator, the CustomEndpoint parameter. By default, applications instrumented with Dotfuscator CE will send usage data to the free Runtime Intelligence endpoint. CodePlex projects need to send usage data to the commercial version of the endpoint. Set the CustomEndpoint parameter to so-s.info/PreEmptive.Web.Services.Messaging/MessagingServiceV2.asmx. The Teardown attribute does not require setting any parameter values.

Setup and Teardown

Once our application has the analytics code injected into it by Dotfuscator every time it is run in the wild it will transmit startups, shutdowns and some basic runtime environment information back to the portal. We can now expand on this concept and instrument our application to send back which features of our application are used.

There are two types of feature usage tracking. One, where the number of invocations of a decorated method are summarized; and two, where the duration of use is also measured. Reporting on the number of uses of a method is accomplished by decorating that method with a Feature attribute. In our example application we will track the number of times the user sets the data source URI by pressing the button. To accomplish this, decorate the buttons click event handler with a Feature attribute and set the name parameter to the string value we want to display as the feature name. We will call this feature "ChangeURI" and not change the value of any of the other parameters.

ChangeURI Feature

The second type of feature tracking, measuring the duration of execution, is implemented by decorating with two Feature attributes, one of type Start and a second of type Stop. In our example we would like to measure how long it takes our asynchronous data query service to execute and display updated data to the user. First, we decorate the RefreshChart method with a Feature attribute named "RefreshChart" and an EventType of Start. Next, we decorate the QueryAppUsesCompleted method with a Feature attribute also named "RefreshChart" with an EventType of Stop.

RefreshChart Start

RefreshChart Stop

All that remains is to compile and perform the code injection by processing our application binary with Dotfuscator. From the Visual Studio 2010 Tools menu, select the Dotfuscator Software Services entry. After Dotfuscator starts add the application assembly by selecting the Input Assemblies menu node and adding all application binaries to the Input Assemblies section. Next, turn off the renaming obfuscation feature by right clicking on the Renaming node and unchecking the "Enable" option.

Dotfuscator Input

Select the Instrumentation menu node and select the Options tab. Check the "Enable Instrumentation" and "Send application analytics messages" options as those enable code injection in Dotfuscator.

Enable Instrumentation

Selecting the Attributes tab we can use the Dotfuscator user interface to visually verify the injection points. Additional injection points can be added from the user interface by right clicking on the appropriate method and adding the appropriate attribute. Injection points created in this manner do not require code modification and are only stored in the Dotfuscator configuration file. We can also modify the properties of injection points that are defined in the source code by changing the values in the user interface. In this case Dotfuscator will merge the parameter values prior to injection with the values defined from the user interface taking precedent in the event of a conflict.

Instrumentation Before

We can take advantage of the ability to modify values by adding the ability for a user to opt out of having their usage activity aggregated. The example program has already data bound a user configuration property named OptIn to the checkbox displayed on the main window and exposed it with a static property on the application.

OptIn Property

By modifying the Setup property parameters from the user interface we will tell the code injection engine to inject a check of the value of that property and to not send any analytics data if it is false. We set the OptInSourceElement to Property, the OptInSourceName as the name of the property (OptIn) and the OptInSourceOwner as the type that contains the property (App).

OptIn Instrumentation

Building the project in Dotfuscator results in a new set of application binaries in the Dotfuscator output directory (by default a subdirectory named "Dotfuscated" under the location where the Dotfuscator project is saved. These binaries function identically to those emitted by the compiler except that they now have the additional application analytics behavior embedded in them. There are no additional deployment or runtime dependencies for Runtime Intelligence instrumented applications as the only runtime requirement, a small runtime library, is embedded directly into the output assembly.


Our application is now built and ready to be released. We package the instrumented binaries as our download and release them. Now we need to edit our CodePlex project and update the Runtime Intelligence Application ID value in the Statistics section to the same GUID we generated earlier. This will allow CodePlex to include application runs in the project's statistics as well as link to the detailed application usage information.

CodePlex Project Page

We are able to view how many times our application is run by date from the projects CodePlex statistics page. We can also jump to the detailed Runtime Intelligence data by selecting the detailed information navigation link.

Detailed Navigation Link

In the detailed Runtime Intelligence portal on the Application Overview page we see an overview of our application's usage, how many times it has been run in the wild, and on which operating systems and frameworks. We can easily change the view and view a display of how many times per day our application is started but does not send a stop (Incomplete runs). The top features used in our application as well as how long users spend in the application and how many unique users use the application are also summarized.

Application Overview

We can drill into a detailed report of feature usage on the Feature Overview page. Here we are able to plot the activiaty profile of any features used within our application, how often they are used within our application and which features are most likely to be used in an application that does not terminate as expected. We are also shown our most and least used features along with which ones are growing and falling in use the most rapidly.

Feature Overview

The final report, System Profile provides information about the environments that our application runs in. We are able to view both total runs and incomplete runs by Operating System, System RAM, # of processors and framework version.

System Profle

All of the usage data for the application can be compared between individual versions of the application and over various date ranges. By clicking on one of the top links for date range or application you are able to modify the filters for the page. Here you can drill into activity for a specific version of the application over any time frame as well as compare the activity of one version to another.

Filters

Last edited Jul 27 2011 at 7:32 PM by PreEmptive, version 8