Using a WCF Message Inspector to extend AppFabric Monitoring

I read through Ron Jacobs post on Monitoring WCF Data Services with AppFabric

http://blogs.msdn.com/b/endpoint/archive/2010/06/09/tracking-wcf-data-services-with-windows-server-appfabric.aspx

What is immediately striking are 2 things – it’s so easy to get monitoring data into a viewer (AppFabric Dashboard) w/ very little work.  And the 2nd thing is, why can’t this be a WCF message inspector on the dispatch side.

So, I took the base class WCFUserEventProvider that’s located in the WCF/WF samples [1] in the following path, \WF_WCF_Samples\WCF\Basic\Management\AnalyticTraceExtensibility\CS\WCFAnalyticTracingExtensibility\  and then created a few classes that project the injection as a IEndPointBehavior

There are just 3 classes to drive injection of the inspector at runtime via config:

  1. IDispatchMessageInspector implementation
  2. BehaviorExtensionElement implementation
  3. IEndpointBehavior implementation

The full source code is below with a link to the solution file here: [Solution File]

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.ServiceModel.Dispatcher;  
using System.ServiceModel.Channels;  
using System.ServiceModel;  
using System.ServiceModel.Configuration;  
using System.ServiceModel.Description;  
using Microsoft.Samples.WCFAnalyticTracingExtensibility;

namespace Fabrikam.Services  
{
    public class AppFabricE2EInspector : IDispatchMessageInspector
    {
        static WCFUserEventProvider evntProvider = null;
        static AppFabricE2EInspector()
        {
            evntProvider = new WCFUserEventProvider();
        }

        public object AfterReceiveRequest(
            ref Message request,
            IClientChannel channel,
            InstanceContext instanceContext)
        {

            OperationContext ctx = OperationContext.Current;
            var opName = ctx.IncomingMessageHeaders.Action;

            evntProvider.WriteInformationEvent("start", string.Format("operation: {0} at address {1}", opName, ctx.EndpointDispatcher.EndpointAddress));
            return null;
        }

        public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
            OperationContext ctx = OperationContext.Current;
            var opName = ctx.IncomingMessageHeaders.Action;

            evntProvider.WriteInformationEvent("end", string.Format("operation: {0} at address {1}", opName, ctx.EndpointDispatcher.EndpointAddress));

        }
    }

    public class AppFabricE2EBehaviorElement : BehaviorExtensionElement
    {

        #region BehaviorExtensionElement
        /// <summary>
        /// Gets the type of behavior.
        /// </summary>
        /// <value></value>
        /// <returns>The type that implements the end point behavior<see cref="T:System.Type"/>.</returns>
        public override Type BehaviorType
        {
            get { return typeof(AppFabricE2EEndpointBehavior); }
        }

        /// <summary>
        /// Creates a behavior extension based on the current configuration settings.
        /// </summary>
        /// <returns>The behavior extension.</returns>
        protected override object CreateBehavior()
        {
            return new AppFabricE2EEndpointBehavior();
        }

        #endregion BehaviorExtensionElement

    }

    public class AppFabricE2EEndpointBehavior : IEndpointBehavior //, IServiceBehavior
    {

        #region IEndpointBehavior
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {}


        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            throw new NotImplementedException();
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new AppFabricE2EInspector());

        }

        public void Validate(ServiceEndpoint endpoint)
        {
            ;
        }
        #endregion IEndpointBehavior



    }
}

 

 

[1] http://www.microsoft.com/downloads/details.aspx?FamilyID=35ec8682-d5fd-4bc3-a51a-d8ad115a8792&displaylang=en