March 2009 - Posts

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.

Demos from SDWest

Apparently I forgot to blog my demos from my WCF extensibility session at SDWest. You can find them here. Thanks again to all the people who attended my session.

New WS-* specs published

The Web Services Resource Access Working Group published five First Public Working Drafts: Web Services Enumeration (WS-Enumeration), Web Services Eventing (WS-Eventing), Web Services Resource Transfer (WS-RT), Web Services Transfer (WS-Transfer), and Web Services Metadata Exchange (WS-MetadataExchange). The first describes a general SOAP-based protocol for enumerating a sequence of XML elements that is suitable for traversing logs, message queues, or other linear information models. The second describes a protocol that allows Web services to subscribe to or accept subscriptions for event notification. The third defines extensions to WS-Transfer that deal primarily with fragment-based access to resources to satisfy the common requirements of WS-ResourceFramework and WS-Management. The fourth describes a general SOAP-based protocol for accessing XML representations of Web service-based resources. The fifth defines how metadata associated with a Web service endpoint can be represented as resources, how metadata can be embedded in endpoint references, and how metadata could be retrieved from a Web service endpoint.

Speaking at SDWest about WCF extensibility

This Friday I will be presenting a session about WCF extensibility at SDWest . I plan to go deep into a lot of the WCF internals aspects such as the channels, client-dispatcher runtime, metadata, hosting, instancing, etc. My goal is to give you as much information as possible about the different extensibility points of the WCF runtime. We are going to spend the bulk of the sessions looking at code and showing real world scenarios of the applicability of the WCF extensibility model. If you are attending SDWest and you are interested in WCF and Service Orientation in general please swing by my session and feel free to introduce yourself.

The SDWest speaker lineup looks very impressive and it includes great WCF sessions delivered by some of the top minds in the industry such as Michele Bustamante, Juval Lowy, Jon Flanders and Mark Michaelis.

More Posts