using System;
using System.Collections;
using System.Messaging;
using System.Net;
using Pegasus.Log4Net.Core;
using Pegasus.Log4Net.Appender;
namespace Pegasus.Log4Net.Appender
{
/// <summary>
/// Queue appender implementation.
/// </summary>
public class QueueAppender : AppenderSkeleton
{
private MessageQueue messageQueue = null;
private string messageLabel = string.Empty;
private string serverName = string.Empty;
private string queueName = string.Empty;
private int messageType = 0;
#region Properties
/// <summary>
/// The label for the message.
/// </summary>
public string MessageLabel
{
get
{
return messageLabel;
}
set
{
messageLabel = value;
}
}
/// <summary>
/// The type of the message.
/// </summary>
public int MessageType
{
get
{
return messageType;
}
set
{
messageType = value;
}
}
/// <summary>
/// Gets/Sets the server dns name.
/// </summary>
public string Server
{
get
{
return serverName;
}
set
{
serverName = value;
}
}
/// <summary>
/// Gets/Sets the queue name.
/// </summary>
public string Queue
{
get
{
return queueName;
}
set
{
queueName = value;
}
}
#endregion
/// <summary>
/// Queue appender constructor.
/// </summary>
public QueueAppender() : base() { }
/// <summary>
/// Append method implementation.
/// </summary>
/// <param name="loggingEvent">event information</param>
protected override void Append( LoggingEvent loggingEvent )
{
try
{
lock( this )
{
Hashtable messageData = new Hashtable();
messageData.Add( "Namespace", loggingEvent.LoggerName );
messageData.Add( "ServerName", Environment.MachineName );
messageData.Add( "Date", loggingEvent.TimeStamp );
messageData.Add( "Level", loggingEvent.Level.DisplayName );
messageData.Add( "Thread", loggingEvent.ThreadName );
messageData.Add( "Class", loggingEvent.LocationInformation.ClassName );
messageData.Add( "Method", loggingEvent.LocationInformation.MethodName );
messageData.Add( "Line", loggingEvent.LocationInformation.LineNumber );
messageData.Add( "File", loggingEvent.LocationInformation.FileName );
messageData.Add( "Message", loggingEvent.RenderedMessage );
messageData.Add( "Exception", ExceptionHelper.DumpExceptionAll( loggingEvent.ExceptionObject ) );
SendMessage( messageData );
}
}
catch( Exception exception )
{
ErrorHandler.Error( "QueueAppender", exception, ErrorCode.WriteFailure );
}
}
private void SendMessage( Hashtable messageData )
{
try
{
ConfigureQueue();
Message message = new Message();
message.AppSpecific = messageType;
message.Label = messageLabel;
message.Priority = MessagePriority.Normal;
message.Formatter = messageQueue.Formatter;
message.Body = messageData;
messageQueue.Send( message );
}
catch( Exception exception )
{
ErrorHandler.Error( "QueueAppender.SendMessage", exception, ErrorCode.WriteFailure );
}
}
private void ConfigureQueue()
{
if( messageQueue == null )
{
if( string.IsNullOrEmpty( serverName ) )
{
throw new ArgumentException( "Unable to initialize message queue, unkown server", "serverName" );
}
if( string.IsNullOrEmpty( queueName ) )
{
throw new ArgumentException( "Unable to initialize message queue, unkown queue", "queueName" );
}
IPAddress ipAddress = null;
try
{
IPHostEntry hostEntry = Dns.GetHostEntry( serverName );
ipAddress = hostEntry.AddressList[ 0 ];
}
catch( Exception exception )
{
throw new ArgumentException( string.Format( "Unable to locate an IP address for server {0}", serverName ), exception );
}
messageQueue = new MessageQueue( string.Format( @"FORMATNAME:DIRECT=TCP:{0}\{1}", ipAddress.ToString(), queueName ) );
messageQueue.Formatter = new BinaryMessageFormatter();
messageQueue.DefaultPropertiesToSend.TimeToReachQueue = TimeSpan.FromHours( 1.0 );
messageQueue.DefaultPropertiesToSend.TimeToBeReceived = TimeSpan.FromDays( 10.0 );
}
}
}
}