Extending Dublin’s tracking service by implementing a custom tracking participant

In a previous post we've explored how to extend Dublin's forwarding service by implementing a custom message filter. This post continues the series by illustrating the extensibility model of Dublin's tracking service.

WCF message tracking and monitoring are some of the areas that are considerably enhanced by the Windows Application Server (Dublin). As part of its runtime service architecture, Dublin introduces a tracking subsystem that enables the monitoring of WCF service instances. This subsystem captures events produced during the lifetime of a WCF service instance and store them in a persistent repository so that they can be later used on different operational areas such as management, troubleshooting and analysis.

There are various articles, blog posts and presentations that cover in details the functionality of Dublin’s tracking service. We don’t intend to recreate that content as part of this blog port. Instead, we would like to focus on the techniques developers can use to extend the default capabilities of the tracking service. Specifically, this blog post illustrates how to implement a custom tracking participant to customize Dublin’s tracking infrastructure.

The WCF tracking subsystem is powered by a versatile architecture based on four fundamental components:

  • Tracking Records: A tracking record is the fundamental tracking information unit that can be consumed by a tracking participant. The WCF tracking subsystem includes two types of tracking records: service and message.
  • Tracking Participants: A Tracking participant consumes tracking records emitted by tracking subsystems. Windows Application Server ships with the SQLTrackingParticipant that allows you to store tracking information in a data store in an SQL database. Tracking participants receive only the events subscribed to in the tracking profile.
  • Tracking Profile: A tracking profile represents the mechanism by which a tracking participant can subscribe to a specific set of tracking records. Conceptually, a tracking profile is a well defined expresses a filter that can be applied to the different tracking records emitted by the WCF tracking subsystem.
  • Tracking store: A tracking store is a persistent repository that stores a set of tracking records and the relationships between them. The current version of the Dublin Application Servers includes a SQL Server tracking store that can is used by the SQLTrackingParticipant.

A view of the WCF tracking subsystem is illustrated in the following figure.

Figure: Tracking model 

It’s no coincidence that we have highlighted the tracking participant component on the previous figure. Tracking participants are the main extensibility point of the tracking subsystems as they control the processing of the tracking records and the interactions with a specific tracking store.

Developers can extend the WCF tracking subsystem by implementing a custom tracking participant. From a programming model standpoint, this task entails deriving from the System.WorkflowModel.Tracking.TrackingParticipant class and overriding the Track virtual operation as illustrated in the following code:

   1:  public class CustomParticipant : TrackingParticipant 
   2:  {
   3:      public CustomParticipant(NameValueCollection parameters)
   4:              : this()
   5:      {
   6:        ....The implementation has been omitted for brevity....
   7:      }
   8:   
   9:      public override void Track(TrackingRecord record, TimeSpan timeout)
  10:      {
  11:        ....The implementation has been omitted for brevity....
  12:      }
  13:  }

Instead of creating a brand new tracking participant class we can extend one of the existing implementations like the System.WorkflowModel.Tracking.SQLTrackingParticipant which already abstracts the interactions with the SQL tracking database.

   1:  public class CustomTrackingParticipant: SqlTrackingParticipant
   2:  {
   3:    public CustomTrackingParticipant(NameValueCollection parameters)
   4:              : base(parameters)
   5:    { }
   6:   
   7:    public override void  Track(System.WorkflowModel.Tracking.TrackingRecord    
   8:                                              trackingRecord, TimeSpan timeout)
   9:    {
  10:      base.Track(trackingRecord, timeout);
  11:      EventLog.WriteEntry("Custom WCF Tracking Participant", 
  12:      String.Format("Event received: Instance={0}, RecordNumber={1}", 
  13:      trackingRecord.InstanceId.ToString(), 
  14:      trackingRecord.RecordNumber.ToString()), 
  15:      EventLogEntryType.Information);
  16:     }
  17:    }
  18:   

Looking at the previous code, you can notice that our custom tracking participant extends the capabilities of the SQL tracking participant by logging some information to the event log. We can subscribe our tracking participant to specific tracking records via a tracking profile similar to the one illustrated in the following figure:

   1:  <trackingProfiles>
   2:   
   3:      <profile name="CustomTrackingProfile">
   4:        <![CDATA[<TrackingProfile ScopeTarget="*" ScopeType="WF" 
                  xmlns="clr-namespace:System.WorkflowModel.Tracking;assembly=System.WorkflowModel" 
                  xmlns:p="http://schemas.microsoft.com/netfx/2008/xaml/schema">
   5:              <ActivityQuery>
   6:                  <ActivityQuery.States>
   7:                      <p:String>Closed</p:String>
   8:                  </ActivityQuery.States>
   9:                  <ActivityQuery.VariableQueries>
  10:                      <VariableQuery IsRequired="False" Name="order1" VariableName="result" />
  11:                  </ActivityQuery.VariableQueries>
  12:              </ActivityQuery>
  13:          </TrackingProfile>]]>
  14:      </profile>
  15:   
  16:    </trackingProfiles> 

In order to make this profile available to Dublin’s infrastructure we need to import it using the Import Profile IIS extension.

 

After importing the profile we need to register our custom tracking participant. We can do that using the following configuration instructions.

   1:  <trackingComponents>
   2:      <add name="CustomWCFTracking"   
   3:               type="Tellago.ServiceModel.Samples.CustomTrackingParticipant.
   4:              CustomTrackingParticipant, Tellago.ServiceModel.Samples.CustomTrackingParticipant,  
   5:              Version=1.0.0.0, Culture=neutral, PublicKeyToken=b6e6a71f86cc69e9" 
   6:              trackingStore="DefaultMonitoringStore" participateInProcessTransaction="false"  
   7:              profileName="CustomTrackingProfile" />
   8:    </trackingComponents> 
   9:   

Alternatively we can use IIS tracking configuration extension as illustrated in the following figure.

Finally we need to enable tracking in the WCF service we are intending to monitor. We can do that by simply configuring a service behavior as illustrated in the following code.

   1:  <serviceBehaviors>
   2:     <behavior name="CustomTrackingBehavior">
   3:       <serviceTracking>
   4:         <add name="CustomWCFTracking" />
   5:       </serviceTracking>
   6:     </behavior> 
   7:   </serviceBehaviors> 
 

Alternatively we can use the tracking setting IIS extensions.

After this the service is configured to use our custom tracking participant. Consequently, Dublin’s tracking service will generate the tracking records associated with a specific interaction (message sent or receive) and those records will be passed to our custom tracking participant based on the tracking profile we configured previously.

No Comments