Using a WCF Message Inspector to extend AppFabric Monitoring
- by Shawn Cicoria
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:     IDispatchMessageInspector implementation     BehaviorExtensionElement implementation     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