IntelliTrace and CollectionPlan.xml

Even if you’ve already spent some time getting familiar with IntelliTrace (our new debugger logging feature in Visual Studio 2010 Ultimate) and playing around with some of the advanced options you might not be aware of the CollectionPlan.xml file and how important it is to controlling IntelliTrace. This is by design, as the collection plan isn’t the most user friendly thing to edit and contains much deeper options then most users would need to access for basic tasks. That being said, a bit of knowledge about the collection plan can help quite a bit in understanding how IntelliTrace works and can give you some expanded options for tuning IntelliTrace for your own use. This file is also especially important to know about if you plan on running IntelliTrace.exe outside of VS, in that case you will always have to pass it a collection plan so it knows how to operate.

What is the collection plan?

The collection plan is a set of options that details to the actual IntelliTrace.exe program (which is executed under the covers by Visual Studio or Microsoft Test Manager) exactly what data should be collected, when that data should be collected and how to create the resulting log file. When you open up an iTrace file after collection this information has already been packed into the file, that way when we open it up for analysis we know exactly how to decode all the debugging data stored in the file.

When first starting up Visual Studio the options in the Tools->Options menus are populated from the default collection plan that we ship with VS. However, after you start to edit options via Tools->Options the values in VS will diverge from the default values in the included collection plan, so be aware of that when manually looking at or configuring the collection plan. You can see this default CollectionPlan.xml from the following location in your VS install.

C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\TraceDebugger Tools\en

What is defined in the collection plan?

The collection plan contains lots of different options for tuning IntelliTrace collection. Below I’ll try to cover at least the broad sections quickly to help explain what each option controls.

The first section is the StartupInfo section. In here you can set default values for log file name and directory. Also you can truncate log size to a specific maximum. IntelliTrace uses circular buffering, so when that limit is hit the oldest events will start to be evicted from the file to make room for the new ones.

The next section, CheckpointOptions, is one that is unlikely to be of much use to most users. When we collect and load iTrace files we use a checkpointing system to load data in chunks to avoid memory pressure. In this section you can change the mode and rate of checkpointing for both thread and notify point events.

The next series of sections all control enabling or disabling different types of instrumentation as well as controlling any specific binaries or processes that are to be excluded from instrumentation. In each section changing the “enabled” value to true will turn on that specific type of data collection. Each section also has a section of modules and processes to specifically exclude from collection. By changing the isExclusionList from “true” to “false” you will turn this exclusion list to an inclusion list in which only the specified modules will collect data. You can specify modules with a public key token, while for both modules and process you can specify a substring to match for inclusion or exclusion. In the example below (snipped from the default CollectionPlan.xml) you can see that we don’t want IntelliTrace to collect data from modules with “Microsoft.” in the title or from processes devenv.exe or mtm.exe (Microsoft Test Manager).

<TraceInstrumentation enabled="false">

    <Options>PresetFull</Options>

    <ModuleList isExclusionList="true">

      <Name>PublicKeyToken:B77A5C561934E089</Name>

      <Name>Microsoft.</Name>

    </ModuleList>

    <ProcessList isExclusionList="true">

      <Name>devenv.exe</Name>

      <Name>mtm.exe</Name>

    </ProcessList>

  </TraceInstrumentation>

The four different instrumentation categories listed in the collection plan are explained as follows. Trace Instrumentation represents the collection of method enter and exit data. Diagnostic Event Instrumentation represents the collection of data at IntelliTrace events. Web Request Tracking Instrumentation represents the instrumentation that we do to trace IntelliTrace calls across web request boundaries. Detour Instrumentation is actually deprecated and does not affect the current function of IntelliTrace.exe.

After the instrumentation sections there is the TracePointProvider section that makes up the bulk of the collection plan. This section details all of the IntelliTrace events (the Trace Point nomenclature is just an outdated name) that are available for collection. At the start of the section is a Categories section that provides overall categories to group IntelliTrace events into. These are the categories that you will see in the Tools->Options section when selecting IntelliTrace events to enable.

Below the Categories section is a section to define the various modules that we will be referencing in the actual Diagnostic Events. The DiagnosticEventSpecification is the actual heart of the IntelliTrace events, the example below is for the WinForms button clicked gesture.

<DiagnosticEventSpecification enabled="true">

        <CategoryId>gesture</CategoryId>

        <SettingsName _locID="settingsName.Button.OnClick">Windows Forms: Button Clicked</SettingsName>

        <SettingsDescription _locID="settingsDescription.Button.OnClick">A Button on a Windows Forms application was clicked.</SettingsDescription>

    <Bindings>

          <Binding>

            <ModuleSpecificationId>winforms</ModuleSpecificationId>

            <TypeName>System.Windows.Forms.Button</TypeName>

            <MethodName>OnClick</MethodName>

            <MethodId>System.Windows.Forms.Button.OnClick(System.EventArgs):System.Void</MethodId>

            <ProgrammableDataQuery>

              <ModuleName>Microsoft.VisualStudio.DefaultDataQueries.dll</ModuleName>

              <TypeName>Microsoft.VisualStudio.DataQueries.Winforms.Button.OnClickDataQuery</TypeName>

            </ProgrammableDataQuery>

          </Binding>

        </Bindings>

      </DiagnosticEventSpecification>

At the top of the event you can see the enabled field that will control if this event is part of collection (assuming that overall Diagnostic Event Instrumentation is enabled earlier in the file). By default most of the events are turned off and need to be enabled in the VS IDE or the collection plan file (if using IntelliTrace.exe) to be collected. After the main element you have sections to set a category (from the groups that we defined earlier), a name and a description for this specific event. After that is the Binding section that controls when this event is collected. The ModuleSpecificationId, TypeName, MethodName and MethodID fields tell IntelliTrace the exact function that we should collect this event at. In this specific case we are interested in the System.Windows.Forms.Button.OnClick function and every time this function is called in an application running under IntelliTrace we will collect an event.

So that defines when the event is collected. But to understand what data we collect at that point we need to look at the ProgrammableDataQuery section that follows. A programmable data query is the code that runs to actually collect local data of interest when an IntelliTrace event fires. Shown in the screen below is the debugger set back to a WinForms button click event that was previously collected. The Programmable Data Query controls the data that we currently see in the Autos window. For the button click event we’ve created a PDQ to collected the display string of the button in question as this seems the best piece of info for identifying the button when going back over an IntelliTrace log.

In the binary Microsoft.VisualStudio.DefaultDataQueries.dll we define all of the default queries that ship with Visual Studio. It is possible (and customers have already been doing this) that by inheriting from IProgrammableDataQuery you can actually create your own PDQs and use those to create your own IntelliTrace events. Due to time / budget constrains this scenario is not officially supported in this release of IntelliTrace so you won’t see any official documentation on MSDN on this scenario.

With the collection plan introduced and detailed above I’ll look a little deeper at actually running IntelliTrace.exe from the command line with a custom collection plan in a future blog post.

 Ian Huff