Configuring Tracking for a Workflow

A workflow can execute in three ways:

Depending on the workflow hosting option, a tracking participant can be added either through code or through a configuration file. This topic describes how tracking is configured by adding a tracking participant to a WorkflowApplication and to a WorkflowServiceHost, and how to enable tracking when using WorkflowInvoker.

Configuring Workflow Application Tracking

A workflow can run using the WorkflowApplication class. This topic demonstrates how tracking is configured for a .NET Framework 4.6.1 workflow application by adding a tracking participant to the WorkflowApplication workflow host. In this case, the workflow runs as a workflow application. You configure a workflow application through code (rather than by using a configuration file), which is a self-hosted .exe file using the WorkflowApplication class. The tracking participant is added as an extension to the WorkflowApplication instance. This is done by adding the TrackingParticipant to the extensions collection for the WorkflowApplication instance.

For a workflow application, you can add the EtwTrackingParticipant behavior extension as shown in the following code.

LogActivity activity = new LogActivity();

WorkflowApplication instance = new WorkflowApplication(activity);
EtwTrackingParticipant trackingParticipant =
    new EtwTrackingParticipant
{

        TrackingProfile = new TrackingProfile
           {
               Name = "SampleTrackingProfile",
               ActivityDefinitionId = "ProcessOrder",
               Queries = new WorkflowInstanceQuery
               {
                  States = { "*" }
              }
          }
       };
instance.Extensions.Add(trackingParticipant);

Configuring Workflow Service Tracking

A workflow can be exposed as a WCF service when hosted in the WorkflowServiceHost service host. WorkflowServiceHost is a specialized .NET ServiceHost implementation for a workflow-based service. This section explains how to configure tracking for a .NET Framework 4.6.1 workflow service running in WorkflowServiceHost. It is configured through a Web.config file (for a Web-hosted service) or an App.config file (for a service hosted in a stand-alone application, such as a console application) by specifying a service behavior or through code by adding a tracking-specific behavior to the Behaviors collection for the service host.

For a workflow service hosted in WorkflowServiceHost, you can add the EtwTrackingParticipant using the <behavior> element in a configuration file, as shown in the following example.

<behaviors>
   <serviceBehaviors>
        <behavior>
          <etwTracking profileName="Sample Tracking Profile" />
        </behavior>
   </serviceBehaviors>
</behaviors>

Alternatively, for a workflow service hosted in WorkflowServiceHost, you can add the EtwTrackingParticipant behavior extension through code. To add a custom tracking participant, create a new behavior extension and add it to the ServiceHost as shown in the following example code.

Note

If you want to view sample code that shows how to create a custom behavior element that adds a custom tracking participant, refer to the Tracking samples.

ServiceHost svcHost = new ServiceHost(typeof(WorkflowService), new
                                 Uri("http://localhost:8001/Sample"));
EtwTrackingBehavior trackingBehavior =
    new EtwTrackingBehavior
    {
        ProfileName = "Sample Tracking Profile"
    };
svcHost.Description.Behaviors.Add(trackingBehavior);
svcHost.Open();

The tracking participant is added to the workflow service host as an extension to the behavior.

This sample code below shows how to read a tracking profile from configuration file.

TrackingProfile GetProfile(string profileName, string displayName)
        {
            TrackingProfile trackingProfile = null;
            TrackingSection trackingSection = (TrackingSection)WebConfigurationManager.GetSection("system.serviceModel/tracking");
            if (trackingSection == null)
            {
                return null;
            }

            profileName ??= "";

            //Find the profile with the specified profile name in the list of profile found in config
            var match = from p in new List<TrackingProfile>(trackingSection.TrackingProfiles)
                        where (p.Name == profileName) && ((p.ActivityDefinitionId == displayName) || (p.ActivityDefinitionId == "*"))
                        select p;

            if (match.Count() == 0)
            {
                //return an empty profile
                trackingProfile = new TrackingProfile()
                {
                    ActivityDefinitionId = displayName
                };

            }
            else
            {
                trackingProfile = match.First();
            }

            return trackingProfile;

This sample code shows how to add a tracking profile to a workflow host.

WorkflowServiceHost workflowServiceHost = serviceHostBase as WorkflowServiceHost;
if (null != workflowServiceHost)
{
    string workflowDisplayName = workflowServiceHost.Activity.DisplayName;
    TrackingProfile trackingProfile = GetProfile(this.profileName, workflowDisplayName);
    workflowServiceHost.WorkflowExtensions.Add(()  => new EtwTrackingParticipant {
        TrackingProfile = trackingProfile
    });
 }

Note

For more information on tracking profiles, refer to Tracking Profiles.

Configuring tracking using WorkflowInvoker

To configure tracking for a workflow executed using WorkflowInvoker, add the tracking provider as an extension to a WorkflowInvoker instance. The following code example is from the Custom Tracking sample.

WorkflowInvoker invoker = new WorkflowInvoker(BuildSampleWorkflow());
invoker.Extensions.Add(customTrackingParticipant);
invoker.Invoke();

Viewing tracking records in Event Viewer

There are two Event Viewer logs of particular interest to view when tracking WF execution - the Analytic log and the Debug log. Both reside under the Microsoft|Windows|Application Server-Applications node. Logs within this section contain events from a single application rather than events that have an impact on the entire system.

Debug trace events are written to the Debug Log. To collect WF debug trace events in the Event Viewer, enable the Debug Log.

  1. To open Event Viewer, click Start, and then click Run. In the Run dialog, type eventvwr.

  2. In the Event Viewer dialog, expand the Applications and Services Logs node.

  3. Expand the Microsoft, Windows, and Application Server-Applications nodes.

  4. Right-click the Debug node under the Application Server-Applications node, and select Enable Log.

  5. Execute your tracing-enabled application to generate tracing events.

  6. Right-click the Debug node and select Refresh. Tracing events should be visible in the center pane.

WF 4 provides a tracking participant that writes tracking records to an ETW (Event Tracing for Windows) session. The ETW tracking participant is configured with a tracking profile to subscribe to tracking records. When tracking is enabled, errors tracking records are emitted to ETW. ETW tracking events (between the range of 100-113) corresponding to the tracking events emitted by the ETW tracking participant are written to the Analytic Log.

To view tracking records, follow these steps.

  1. To open Event Viewer, click Start, and then click Run. In the Run dialog, type eventvwr.

  2. In the Event Viewer dialog, expand the Applications and Services Logs node.

  3. Expand the Microsoft, Windows, and Application Server-Applications nodes.

  4. Right-click the Analytic node under the Application Server-Applications node, and select Enable Log.

  5. Execute your tracking-enabled application to generate tracking records.

  6. Right-click the Analytic node and select Refresh. Tracking records should be visible in the center pane.

The following image shows tracking events in the event viewer:

Screenshot of the Event Viewer showing tracking records.

Registering an application-specific provider ID

If events need to be written to a specific application log, follow these steps to register the new provider manifest.

  1. Declare the provider ID in the application configuration file.

    <system.serviceModel>
        <diagnostics etwProviderId="2720e974-9fe9-477a-bb60-81fe3bf91eec"/>
    </system.serviceModel>
    
  2. Copy the manifest file from %windir%\Microsoft.NET\Framework\<latest version of .NET Framework 4.6.1>\Microsoft.Windows.ApplicationServer.Applications.man to a temporary location, and rename it to Microsoft.Windows.ApplicationServer.Applications_Provider1.man

  3. Change the GUID in the manifest file to the new GUID.

    <provider name="Microsoft-Windows-Application Server-Applications" guid="{2720e974-9fe9-477a-bb60-81fe3bf91eec}" />
    
  4. Change the provider name if you do not want to uninstall the default provider.

    <provider name="Microsoft-Windows-Application Server-Applications" guid="{2720e974-9fe9-477a-bb60-81fe3bf91eec}" />
    
  5. If you changed the provider name in the previous step, change the channel names in the manifest file to the new provider name.

    <channel name="Microsoft-Windows-Application Server-Applications_Provider1/Admin" chid="ADMIN_CHANNEL" symbol="ADMIN_CHANNEL" type="Admin" enabled="false" isolation="Application" message="$(string.MICROSOFT_WINDOWS_APPLICATIONSERVER_APPLICATIONS.channel.ADMIN_CHANNEL.message)" />
    <channel name="Microsoft-Windows-Application Server-Applications_Provider1/Operational" chid="OPERATIONAL_CHANNEL" symbol="OPERATIONAL_CHANNEL" type="Operational" enabled="false" isolation="Application" message="$(string.MICROSOFT_WINDOWS_APPLICATIONSERVER_APPLICATIONS.channel.OPERATIONAL_CHANNEL.message)" />
    <channel name="Microsoft-Windows-Application Server-Applications_Provider1/Analytic" chid="ANALYTIC_CHANNEL" symbol="ANALYTIC_CHANNEL" type="Analytic" enabled="false" isolation="Application" message="$(string.MICROSOFT_WINDOWS_APPLICATIONSERVER_APPLICATIONS.channel.ANALYTIC_CHANNEL.message)" />
    <channel name="Microsoft-Windows-Application Server-Applications_Provider1/Debug" chid="DEBUG_CHANNEL" symbol="DEBUG_CHANNEL" type="Debug" enabled="false" isolation="Application" message="$(string.MICROSOFT_WINDOWS_APPLICATIONSERVER_APPLICATIONS.channel.DEBUG_CHANNEL.message)" />
    <channel name="Microsoft-Windows-Application Server-Applications_Provider1/Perf" chid="PERF_CHANNEL" symbol="PERF_CHANNEL" type="Analytic" enabled="false" isolation="Application" message="$(string.MICROSOFT_WINDOWS_APPLICATIONSERVER_APPLICATIONS.channel.PERF_CHANNEL.message)" />
    
  6. Generate the resource DLL by following these steps.

    1. Install the Windows SDK. The Windows SDK includes the message compiler (mc.exe) and resource compiler (rc.exe).

    2. In a Windows SDK command prompt, run mc.exe on the new manifest file.

      mc.exe Microsoft.Windows.ApplicationServer.Applications_Provider1.man
      
    3. Run rc.exe on the resource file generated in the previous step.

      rc.exe  Microsoft.Windows.ApplicationServer.Applications_Provider1.rc
      
    4. Create an empty cs file called NewProviderReg.cs.

    5. Create a resource DLL using the C# compiler.

      csc /target:library /win32res:Microsoft.Windows.ApplicationServer.Applications_Provider1.res NewProviderReg.cs /out:Microsoft.Windows.ApplicationServer.Applications_Provider1.dll
      
    6. Change the resource and message dll name in the manifest file from Microsoft.Windows.ApplicationServer.Applications.Provider1.man to the new dll name.

      <provider name="Microsoft-Windows-Application Server-Applications_Provider1" guid="{2720e974-9fe9-477a-bb60-81fe3bf91eec}" symbol="Microsoft_Windows_ApplicationServer_ApplicationEvents" resourceFileName="<dll directory>\Microsoft.Windows.ApplicationServer.Applications_Provider1.dll" messageFileName="<dll directory>\Microsoft.Windows.ApplicationServer.Applications_Provider1.dll" />
      
    7. Use wevtutil to register the manifest.

      wevtutil im Microsoft.Windows.ApplicationServer.Applications_Provider1.man
      

See also