//*****************************************************************************
// Description.....Logging a MessageInspector on the Console
//
// Author..........Roman Kiss, rkiss@pathcom.com
/// Copyright © 2005 ATZ Consulting Inc. (see included license.rtf file)
//
// Date Created: 06/06/05
//
// Date Modified By Description
//-----------------------------------------------------------------------------
// 06/06/05 Roman Kiss Initial Revision
// 02/22/06 Roman Kiss Version FebCTP 2006
// 07/07/06 Roman Kiss Version JuneCTP 2006
// 10/10/11 Roman Kiss Version for ServiceBus
//*****************************************************************************
//
#region References
using System;
using System.Configuration;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Configuration;
#endregion
namespace RKiss.Logger
{
#region LogMessageInspector
/// <summary>
/// Publisher class
/// </summary>
public class LogMessageInspector : IDispatchMessageInspector, IClientMessageInspector
{
#region Properties
// stub
bool _logAfterReceiveRequest = true;
bool _logBeforeSendReply = true;
// proxy
bool _logAfterReceiveReply = true;
bool _logBeforeSendRequest = true;
public bool LogAfterReceiveRequest
{
get { return _logAfterReceiveRequest; }
set { _logAfterReceiveRequest = value; }
}
public bool LogBeforeSendReply
{
get { return _logBeforeSendReply; }
set { _logBeforeSendReply = value; }
}
public bool LogAfterReceiveReply
{
get { return _logAfterReceiveReply; }
set { _logAfterReceiveReply = value; }
}
public bool LogBeforeSendRequest
{
get { return _logBeforeSendRequest; }
set { _logBeforeSendRequest = value; }
}
public ServiceEndpoint Endpoint { get; set; }
#endregion
#region IStubMessageInspector
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
if (LogAfterReceiveRequest && request != null)
{
using (MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue))
{
Message msg = buffer.CreateMessage();
Console.ForegroundColor = msg.IsFault ? ConsoleColor.Red : ConsoleColor.Yellow;
Console.WriteLine("\n>>>>> [{2}] ReceivedRequest {0}\n{1}\n", msg.Headers.MessageId, msg, channel.LocalAddress.Uri);
Console.ResetColor();
request = msg;
}
ShowBrokeredMessageProperty(request.Properties);
}
return request;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
if (LogBeforeSendReply && reply != null)
{
using (MessageBuffer buffer = reply.CreateBufferedCopy(int.MaxValue))
{
Message msg = buffer.CreateMessage();
Console.ForegroundColor = msg.IsFault ? ConsoleColor.Red : ConsoleColor.Green;
Console.WriteLine("\n<<<<< SendReply {0}\n{1}\n", msg.Headers.ReplyTo, msg);
Console.ResetColor();
reply = msg;
}
ShowBrokeredMessageProperty(reply.Properties);
}
}
#endregion
#region IProxyMessageInspector
public void AfterReceiveReply(ref Message reply, object correlationState)
{
if (LogAfterReceiveReply && reply != null)
{
using (MessageBuffer buffer = reply.CreateBufferedCopy(int.MaxValue))
{
Message msg = buffer.CreateMessage();
Console.ForegroundColor = msg.IsFault ? ConsoleColor.Red : ConsoleColor.Green;
if (msg.Headers.RelatesTo != null)
Console.WriteLine("\n>>>>>> [{2}] ReceivedReply {0}\n{1}\n", msg.Headers.RelatesTo, msg, this.Endpoint.Name??"?" );
else
Console.WriteLine("\n>>>>>> [{2}] ReceivedReply {0}\n{1}\n", "?", msg, this.Endpoint.Name??"?");
Console.ResetColor();
reply = msg;
}
ShowBrokeredMessageProperty(reply.Properties);
}
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
if (LogBeforeSendRequest && request != null)
{
using (MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue))
{
Message msg = buffer.CreateMessage();
Console.ForegroundColor = msg.IsFault ? ConsoleColor.Red : ConsoleColor.Yellow;
Console.WriteLine("\n>>>>> [{2}] SendRequest {0}\n{1}\n", msg.Headers.MessageId, msg, this.Endpoint.Name??"?");
Console.ResetColor();
request = msg;
}
ShowBrokeredMessageProperty(request.Properties);
}
return request;
}
#endregion
private void ShowBrokeredMessageProperty(MessageProperties mp)
{
// service bus
if (mp.ContainsKey(Microsoft.ServiceBus.Messaging.BrokeredMessageProperty.Name))
{
var bmp = mp[Microsoft.ServiceBus.Messaging.BrokeredMessageProperty.Name] as Microsoft.ServiceBus.Messaging.BrokeredMessageProperty;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("BrokeredMessageProperty [Label={0}, TTL={1}]", bmp.Label, bmp.TimeToLive);
foreach (var prop in bmp.Properties)
{
if(prop.Value.GetType() == typeof(string) || prop.Value.GetType() == typeof(Guid))
Console.WriteLine(" {0} = '{1}'", prop.Key, prop.Value.ToString());
else
Console.WriteLine(" {0} = {1}", prop.Key, prop.Value.ToString());
}
Console.WriteLine("\r\n");
Console.ResetColor();
}
}
}
#endregion
#region LoggerAttribute
/// <summary>
/// Plumbing class
/// </summary>
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class)]
public class LoggerAttribute : Attribute, IEndpointBehavior, IServiceBehavior
{
#region Properties
bool _enable = true;
bool _logAfterReceiveRequest = true;
bool _logBeforeSendReply = true;
bool _logAfterReceiveReply = true;
bool _logBeforeSendRequest = true;
public bool Enable
{
get { return _enable; }
set { _enable = value; }
}
public bool LogAfterReceiveRequest
{
get { return _logAfterReceiveRequest; }
set { _logAfterReceiveRequest = value; }
}
public bool LogBeforeSendReply
{
get { return _logBeforeSendReply; }
set { _logBeforeSendReply = value; }
}
public bool LogAfterReceiveReply
{
get { return _logAfterReceiveReply; }
set { _logAfterReceiveReply = value; }
}
public bool LogBeforeSendRequest
{
get { return _logBeforeSendRequest; }
set { _logBeforeSendRequest = value; }
}
#endregion
#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters)
{
//nothing to do;
}
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
{
if (Enable)
{
LogMessageInspector inspector = new LogMessageInspector();
inspector.LogAfterReceiveRequest = LogAfterReceiveRequest;
inspector.LogBeforeSendReply = LogBeforeSendReply;
inspector.LogAfterReceiveReply = LogAfterReceiveReply;
inspector.LogBeforeSendRequest = LogBeforeSendRequest;
inspector.Endpoint = serviceEndpoint;
behavior.MessageInspectors.Add(inspector);
}
}
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
{
LogMessageInspector inspector = new LogMessageInspector();
inspector.LogAfterReceiveRequest = LogAfterReceiveRequest;
inspector.LogBeforeSendReply = LogBeforeSendReply;
inspector.LogAfterReceiveReply = LogAfterReceiveReply;
inspector.LogBeforeSendRequest = LogBeforeSendRequest;
inspector.Endpoint = serviceEndpoint;
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
}
public void Validate(ServiceEndpoint serviceEndpoint)
{
//nothing to do;
}
#endregion
#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
{
//nothing to do;
}
public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Endpoints in the Service '{0}'", description.ConfigurationName);
foreach (ServiceEndpoint se in description.Endpoints)
Console.WriteLine(" {0}", se.Address.ToString());
Console.WriteLine("");
Console.ResetColor();
foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher epdispatch in cd.Endpoints)
{
ApplyDispatchBehavior(null, epdispatch);
}
}
}
public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
{
//nothing to do;
}
#endregion
}
#endregion
#region LoggerBehaviorElement
/// <summary>
/// Configuration class
/// </summary>
public class LoggerBehaviorElement : BehaviorExtensionElement
{
#region Constructor(s)
public LoggerBehaviorElement()
{
}
#endregion
#region ConfigurationProperties
[ConfigurationProperty("enable", DefaultValue = true)]
public bool Enable
{
get { return (bool)base["enable"]; }
set { base["enable"] = value; }
}
[ConfigurationProperty("logAfterReceiveRequest", DefaultValue = true)]
public bool LogAfterReceiveRequest
{
get { return (bool)base["logAfterReceiveRequest"]; }
set { base["logAfterReceiveRequest"] = value; }
}
[ConfigurationProperty("logBeforeSendReply", DefaultValue = true)]
public bool LogBeforeSendReply
{
get { return (bool)base["logBeforeSendReply"]; }
set { base["logBeforeSendReply"] = value; }
}
[ConfigurationProperty("logAfterReceiveReply", DefaultValue = true)]
public bool LogAfterReceiveReply
{
get { return (bool)base["logAfterReceiveReply"]; }
set { base["logAfterReceiveReply"] = value; }
}
[ConfigurationProperty("logBeforeSendRequest", DefaultValue = true)]
public bool LogBeforeSendRequest
{
get { return (bool)base["logBeforeSendRequest"]; }
set { base["logBeforeSendRequest"] = value; }
}
#endregion
#region BehaviorExtensionSection
protected override object CreateBehavior()
{
LoggerAttribute logger = new LoggerAttribute();
logger.Enable = (bool)this["enable"];
logger.LogAfterReceiveRequest = (bool)this["logAfterReceiveRequest"];
logger.LogBeforeSendReply = (bool)this["logBeforeSendReply"];
logger.LogAfterReceiveReply = (bool)this["logAfterReceiveReply"];
logger.LogBeforeSendRequest = (bool)this["logBeforeSendRequest"];
return logger;
}
public override void CopyFrom(ServiceModelExtensionElement from)
{
base.CopyFrom(from);
LoggerBehaviorElement section = (LoggerBehaviorElement)from;
this.Enable = section.Enable;
this.LogAfterReceiveRequest = section.LogAfterReceiveRequest;
this.LogBeforeSendReply = section.LogBeforeSendReply;
this.LogAfterReceiveRequest = section.LogAfterReceiveRequest;
this.LogAfterReceiveReply = section.LogAfterReceiveReply;
this.LogBeforeSendRequest = section.LogBeforeSendRequest;
}
protected override ConfigurationPropertyCollection Properties
{
get
{
ConfigurationPropertyCollection collection = new ConfigurationPropertyCollection();
collection.Add(new ConfigurationProperty("enable", typeof(bool), true));
collection.Add(new ConfigurationProperty("logAfterReceiveRequest", typeof(bool), true));
collection.Add(new ConfigurationProperty("logBeforeSendReply", typeof(bool), true));
collection.Add(new ConfigurationProperty("logAfterReceiveReply", typeof(bool), true));
collection.Add(new ConfigurationProperty("logBeforeSendRequest", typeof(bool), true));
return collection;
}
}
#endregion
public override Type BehaviorType
{
get { return typeof(LoggerAttribute); }
}
}
#endregion
}