public string Create(LoggingEvent loggingEvent)
        {
            var data = new Dictionary<string, object>();

            data["level"] = loggingEvent.Level.ToString();
            data["machine"] = Environment.MachineName;
            data["message"] = loggingEvent.RenderedMessage;
            data["timestamp"] = ConvertDateTime(loggingEvent.TimeStamp);
            data["thread"] = loggingEvent.ThreadName;
            data["logger"] = loggingEvent.LoggerName;

            if (loggingEvent.LocationInformation != null)
            {
                data["file"] = loggingEvent.LocationInformation.FileName;
                data["line"] = loggingEvent.LocationInformation.LineNumber;
                data["method"] = loggingEvent.LocationInformation.MethodName;
                data["class"] = loggingEvent.LocationInformation.ClassName;
            }

            var exceptionString = loggingEvent.GetExceptionStrRep();

            if (!string.IsNullOrEmpty(exceptionString))
            {
                data["exception"] = exceptionString;
            }

            AddHttpUrl(data);
            AddHttpUser(data);
            AddHttpUrlReferrer(data);

            return _serializer.Serialize(data);
        }
		/// <summary>
		/// Appends a <paramref name="loggingEvent"/> to the buffer.
		/// </summary>
		/// <param name="loggingEvent">The event to append to the buffer.</param>
		/// <param name="discardedLoggingEvent">The event discarded from the buffer, if any.</param>
		/// <returns><c>true</c> if the buffer is not full, otherwise <c>false</c>.</returns>
		public bool Append(LoggingEvent loggingEvent, out LoggingEvent discardedLoggingEvent) 
		{	
			discardedLoggingEvent = null;

			if (loggingEvent == null)
			{
				throw new ArgumentNullException("loggingEvent");
			}
			lock(this)
			{
				// save the discarded event
				discardedLoggingEvent = m_ea[m_last];

				// overwrite the last event position
				m_ea[m_last] = loggingEvent;	
				if (++m_last == m_maxSize)
				{
					m_last = 0;
				}

				if (m_numElems < m_maxSize)
				{
					m_numElems++;
				}
				else if (++m_first == m_maxSize)
				{
					m_first = 0;
				}

				return (m_numElems < m_maxSize);
			}
		}
Exemple #3
0
        public override FilterDecision Decide(LoggingEvent loggingEvent)
        {
            if (loggingEvent == null)
                throw new ArgumentNullException("loggingEvent");

            var exceptionMessage = loggingEvent.GetExceptionStrRep();
            if (string.IsNullOrEmpty(exceptionMessage))
            {
                return FilterDecision.NEUTRAL;
            }

            if (RegexToMatch != null)
            {
                var regex = new Regex(RegexToMatch, RegexOptions.Multiline);

                if (!regex.Match(exceptionMessage).Success)
                    return FilterDecision.NEUTRAL;

                return AcceptOnMatch ? FilterDecision.ACCEPT : FilterDecision.DENY;
            }

            if (StringToMatch == null || exceptionMessage.IndexOf(StringToMatch) == -1)
            {
                return FilterDecision.NEUTRAL;
            }

            return AcceptOnMatch ? FilterDecision.ACCEPT : FilterDecision.DENY;
        }
        protected override void Append(LoggingEvent loggingEvent)
        {
            byte[] bodyBytes;

            try
            {
                var bodyString = BodyFormatter.Create(loggingEvent);

                bodyBytes = Encoding.UTF8.GetBytes(bodyString);
            }
            catch (Exception e)
            {
                ErrorHandler.Error("Failed creating JSON", e);

                return;
            }

            var request = (HttpWebRequest)WebRequest.Create(Url);

            request.Method = "POST";
            request.ContentType = BodyFormatter.ContentType;
            request.BeginGetRequestStream(r =>
                                              {
                                                  try
                                                  {
                                                      var stream = request.EndGetRequestStream(r);

                                                      stream.BeginWrite(bodyBytes, 0, bodyBytes.Length, c =>
                                                                                                            {
                                                                                                                try
                                                                                                                {
                                                                                                                    stream.Dispose();

                                                                                                                    request.BeginGetResponse(a =>
                                                                                                                                                 {
                                                                                                                                                     try
                                                                                                                                                     {
                                                                                                                                                         request.EndGetResponse(a);
                                                                                                                                                     }
                                                                                                                                                     catch (Exception e)
                                                                                                                                                     {
                                                                                                                                                         ErrorHandler.Error(
                                                                                                                                                             "Failed to get response",
                                                                                                                                                             e);
                                                                                                                                                     }
                                                                                                                                                 }, null);
                                                                                                                    stream.EndWrite(c);
                                                                                                                }
                                                                                                                catch (Exception e)
                                                                                                                {
                                                                                                                    ErrorHandler.Error("Failed to write", e);
                                                                                                                }
                                                                                                            }, null);
                                                  }
                                                  catch (Exception e)
                                                  {
                                                      ErrorHandler.Error("Failed to connect", e);
                                                  }
                                              }, null);
        }
		/// <summary>
		/// This method is called by the <see cref="AppenderSkeleton.DoAppend"/>
		/// method. 
		/// </summary>
		/// <param name="loggingEvent">The event to log.</param>
		override protected void Append(LoggingEvent loggingEvent) 
		{
			// Pass the logging event on the the attached appenders
			if (m_aai != null)
			{
				m_aai.AppendLoopOnAppenders(loggingEvent);
			}
		} 
		/// <summary>
		/// Gets the exception text from the logging event
		/// </summary>
		/// <param name="loggingEvent">the event being logged</param>
		/// <returns>the formatted string</returns>
		override public string Format(LoggingEvent loggingEvent) 
		{
			if (loggingEvent == null)
			{
				throw new ArgumentNullException("loggingEvent");
			}

			return loggingEvent.GetExceptionStrRep();
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="CyclicBuffer" /> class with 
		/// the specified maximum number of buffered logging events.
		/// </summary>
		/// <param name="maxSize">The maximum number of logging events in the buffer.</param>
		/// <exception cref="ArgumentOutOfRangeException">The <paramref name="maxSize"/> argument is not a positive integer.</exception>
		public CyclicBuffer(int maxSize) 
		{
			if (maxSize < 1) 
			{
				throw new ArgumentOutOfRangeException("Parameter: maxSize, Value: [" + maxSize + "] out of range. Non zero positive integer required");
			}
			m_maxSize = maxSize;
			m_ea = new LoggingEvent[maxSize];
			m_first = 0;
			m_last = 0;
			m_numElems = 0;
		}
        public override FilterDecision Decide(LoggingEvent loggingEvent)
        {
            if (loggingEvent == null)
            {
                throw new ArgumentNullException("loggingEvent");
            }

            var loggingEventData = loggingEvent.GetLoggingEventData();
            if (loggingEventData.ExceptionString != null && loggingEventData.ExceptionString.Contains(FilterValue))
            {
                return FilterDecision.DENY;
            }

            return FilterDecision.NEUTRAL;
        }
		/// <summary>
		/// Send the contents of the buffer to the remote sink.
		/// </summary>
		/// <param name="events">The events to send.</param>
		override protected void SendBuffer(LoggingEvent[] events)
		{
			string hostName = SystemInfo.HostName;

			// Set the hostname
			foreach(LoggingEvent e in events)
			{
				if (e.Properties[LoggingEvent.HostNameProperty] == null)
				{
					e.Properties[LoggingEvent.HostNameProperty] = hostName;
				}
			}

			// Send the events
			m_sinkObj.LogEvents(events);
		}
		/// <summary>
		/// Actual writing occurs here.
		/// <para>Most subclasses of <see cref="AppenderSkeleton"/> will need to 
		/// override this method.</para>
		/// </summary>
		/// <param name="loggingEvent">the event to log</param>
		override protected void Append(LoggingEvent loggingEvent) 
		{
			// check if log4net is running in the context of an ASP.NET application
			if (HttpContext.Current != null) 
			{
				// check if tracing is enabled for the current context
				if (HttpContext.Current.Trace.IsEnabled) 
				{
					if (loggingEvent.Level >= Level.WARN) 
					{
						HttpContext.Current.Trace.Warn(loggingEvent.LoggerName, RenderLoggingEvent(loggingEvent));
					}
					else 
					{
						HttpContext.Current.Trace.Write(loggingEvent.LoggerName, RenderLoggingEvent(loggingEvent));
					}
				}
			}
		}
		/// <summary>
		/// A template method for formatting in a converter specific way.
		/// </summary>
		/// <param name="buffer"><see cref="StringBuilder" /> that will receive the formatted result.</param>
		/// <param name="loggingEvent">The <see cref="LoggingEvent" /> on which the pattern converter should be executed.</param>
		virtual public void Format(StringBuilder buffer, LoggingEvent loggingEvent) 
		{
			string s = Convert(loggingEvent);

			if (s == null) 
			{
				if (0 < m_min)
				{
					SpacePad(buffer, m_min);
				}
				return;
			}

			int len = s.Length;

			if (len > m_max)
			{
				buffer.Append(s.Substring(len - m_max));
			}
			else if (len < m_min) 
			{
				if (m_leftAlign) 
				{	
					buffer.Append(s);
					SpacePad(buffer, m_min - len);
				}
				else 
				{
					SpacePad(buffer, m_min - len);
					buffer.Append(s);
				}
			}
			else
			{
				buffer.Append(s);
			}
		}	
		/// <summary>
		/// Calls the <see cref="IAppender.DoAppend" /> method on all 
		/// attached appenders.
		/// </summary>
		/// <param name="loggingEvent">The event being logged.</param>
		/// <returns>The number of appenders called.</returns>
		public int AppendLoopOnAppenders(LoggingEvent loggingEvent) 
		{
			if (loggingEvent == null)
			{
				throw new ArgumentNullException("loggingEvent");
			}
			if (m_appenderList == null) 
			{
				return 0;
			}

			foreach(IAppender appender in m_appenderList)
			{
				try
				{
					appender.DoAppend(loggingEvent);
				}
				catch(Exception ex)
				{
					LogLog.Error("AppenderAttachedImpl: Failed to append to appender [" + appender.Name + "]", ex);
				}
			}
			return m_appenderList.Count;
		}
			/// <summary>
			/// Overridden by subclasses to get the fully qualified name before the
			/// precision is applied to it.
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the fully qualified name</returns>
			abstract protected string GetFullyQualifiedName(LoggingEvent loggingEvent);
			/// <summary>
			/// Convert the pattern to the rendered message
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the relevant location information</returns>
			override protected string Convert(LoggingEvent loggingEvent) 
			{
				LocationInfo locationInfo = loggingEvent.LocationInformation;
				switch(m_type) 
				{
					case FULL_LOCATION_CONVERTER: 
						return locationInfo.FullInfo;

					case METHOD_LOCATION_CONVERTER: 
						return locationInfo.MethodName;

					case LINE_LOCATION_CONVERTER: 
						return locationInfo.LineNumber;

					case FILE_LOCATION_CONVERTER: 
						return locationInfo.FileName;

					default: 
						return null;
				}
			}
			/// <summary>
			/// Convert the pattern into the rendered message
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns></returns>
			override protected string Convert(LoggingEvent loggingEvent) 
			{
				m_date = loggingEvent.TimeStamp;
				string converted = null;
				try 
				{
					converted = m_df.FormatDate(m_date, new StringBuilder()).ToString();
				}
				catch (Exception ex) 
				{
					LogLog.Error("PatternParser: Error occurred while converting date.", ex);
				}
				return converted;
			}
			/// <summary>
			/// To the conversion
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the result of converting the pattern</returns>
			override protected string Convert(LoggingEvent loggingEvent) 
			{
				object prop = loggingEvent.Properties[m_key];
				if (prop != null)
				{
					return prop.ToString();
				}
				return null;
			}
			/// <summary>
			/// To the conversion
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the result of converting the pattern</returns>
			override protected string Convert(LoggingEvent loggingEvent) 
			{
				return loggingEvent.LookupMappedContext(m_key);
			}
		/// <summary>
		/// Check if this filter should allow the event to be logged
		/// </summary>
		/// <remarks>
		/// The <see cref="MDC"/> is matched against the <see cref="StringToMatch"/>.
		/// If the <see cref="StringToMatch"/> occurs as a substring within
		/// the message then a match will have occurred. If no match occurs
		/// this function will return <see cref="FilterDecision.NEUTRAL"/>
		/// allowing other filters to check the event. If a match occurs then
		/// the value of <see cref="AcceptOnMatch"/> is checked. If it is
		/// true then <see cref="FilterDecision.ACCEPT"/> is returned otherwise
		/// <see cref="FilterDecision.DENY"/> is returned.
		/// </remarks>
		/// <param name="loggingEvent">the event being logged</param>
		/// <returns>see remarks</returns>
		override public FilterDecision Decide(LoggingEvent loggingEvent) 
		{
			if (loggingEvent == null)
			{
				throw new ArgumentNullException("loggingEvent");
			}

			// Check if we have a key to lookup the MDC value with
			if (m_key == null)
			{
				// We cannot filter so allow the filter chain
				// to continue processing
				return FilterDecision.NEUTRAL;
			}

			// Lookup the string to match in from the MDC using 
			// the key specified.
			string msg = loggingEvent.LookupMappedContext(m_key);

			// Check if we have been setup to filter
			if (msg == null || (m_stringToMatch == null && m_regexToMatch == null))
			{
				// We cannot filter so allow the filter chain
				// to continue processing
				return FilterDecision.NEUTRAL;
			}
    
			// Firstly check if we are matching using a regex
			if (m_regexToMatch != null)
			{
				// Check the regex
				if (m_regexToMatch.Match(msg).Success == false)
				{
					// No match, continue processing
					return FilterDecision.NEUTRAL;
				} 

				// we've got a match
				if (m_acceptOnMatch) 
				{
					return FilterDecision.ACCEPT;
				} 
				return FilterDecision.DENY;
			}
			else if (m_stringToMatch != null)
			{
				// Check substring match
				if (msg.IndexOf(m_stringToMatch) == -1) 
				{
					// No match, continue processing
					return FilterDecision.NEUTRAL;
				} 

				// we've got a match
				if (m_acceptOnMatch) 
				{
					return FilterDecision.ACCEPT;
				} 
				return FilterDecision.DENY;
			}
			return FilterDecision.NEUTRAL;
		}
			/// <summary>
			/// Gets the fully qualified name of the logger
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the logger name</returns>
			override protected string GetFullyQualifiedName(LoggingEvent loggingEvent) 
			{
				return loggingEvent.LoggerName;
			}
        /// <summary>
        /// Sends the given log event to Common.Logging
        /// </summary>
        /// <param name="loggingEvent">
        /// The logging Event.
        /// </param>
        protected override void Append(LoggingEvent loggingEvent)
        {
            var logger = LogManager.GetLogger(loggingEvent.LoggerName);
            var closestLevel = GetClosestLevel(loggingEvent.Level);
            var logMethod = logMethods[closestLevel];
            loggingEvent.Fix = FixFlags.LocationInfo;

            // Using reflection to get the exception for this logging event for old version of log4net that is wrapped by Sitecore.Logging
            // New versions of log4net expose the exception
            var exception = loggingEvent.GetPrivatePropertyValue<Exception>("m_thrownException");
            logMethod(logger, () => this.RenderLoggingEvent(loggingEvent), exception);
        }
        protected override void Append(log4net.spi.LoggingEvent loggingEvent)
        {
            try
            {
                // We are not checking LogLevel -- That has been added at FilterLevel
                // in Configuration
                // Thanks : http://sitecoreblog.alexshyba.com/2010/07/sitecore-logging-part-3-adding-custom.html#more
                if (Sitecore.Context.Site != null)
                {
                    var properties = loggingEvent.Properties;

                    // By Default Everything comes as a Shell
                    // So, Here we are string RAW Message parsing it using
                    // http://blogs.msdn.com/b/simonince/archive/2009/07/09/string-unformat-i-ve-created-a-monster.aspx


                    // User is perfect!
                    if (Sitecore.Context.User != null)
                    {
                        properties["scuser"] = Sitecore.Context.User.Name;
                    }

                    if (!string.IsNullOrWhiteSpace(loggingEvent.RenderedMessage))
                    {
                        string auditRAWMessage = loggingEvent.RenderedMessage;

                        object[] ParsedValues = AuditUnformatItem(@auditRAWMessage);
                        if (ParsedValues != null && ParsedValues.Any())
                        {
                            // 0 - UserName, 1 - Action, 2 - DatabaseName
                            // 3 - ItemPath, 4 - Language, 5 - Version, 6 - ItemID
                            // 7 - Misc e.g. When you rename item you get new item name
                            // WORKFLOW : 7 - Command, 8 - Previous State
                            // 9 - Next State, 10 - User

                            SetPropertyValue(properties, ParsedValues, "scaction", 1);

                            if (properties["scaction"] != null && !string.IsNullOrWhiteSpace(Convert.ToString(properties["scaction"])) &&
                                Convert.ToString(properties["scaction"]) == "Restore")
                            {
                                return; // We don't process Restore as we don't have all details
                            }
                            SetPropertyValue(properties, ParsedValues, "scitemid", 6);

                            if (ParsedValues.Length > 2)
                            {
                                string databaseName = Convert.ToString(ParsedValues.GetValue(2));
                                if (!string.IsNullOrWhiteSpace(databaseName))
                                {
                                    Sitecore.Data.Database database =
                                        Sitecore.Configuration.Factory.GetDatabase(databaseName);
                                    if (database != null && properties["scitemid"] != null)
                                    {
                                        Sitecore.Data.Items.Item item =
                                            database.GetItem(Convert.ToString(properties["scitemid"]));
                                        if (item != null)
                                        {
                                            properties["sitename"] = item.GetContextSite().Name;
                                        }
                                    }
                                }
                            }

                            SetPropertyValue(properties, ParsedValues, "scitempath", 3);
                            SetPropertyValue(properties, ParsedValues, "sclanguage", 4);
                            SetPropertyValue(properties, ParsedValues, "scversion", 5);
                            SetPropertyValue(properties, ParsedValues, "scmisc", 7);

                            // Workflow
                            SetPropertyValue(properties, ParsedValues, "scmisc", 8, true);
                            SetPropertyValue(properties, ParsedValues, "scmisc", 9, true);
                            SetPropertyValue(properties, ParsedValues, "scmisc", 10, true);
                        }
                    }
                }
                base.Append(loggingEvent);
            }
            catch (Exception ex)
            {
                Sitecore.Diagnostics.Log.Error("Append method failed to record information", ex, this);
            }
        }
		/// <summary>
		/// Resizes the cyclic buffer to <paramref name="newSize"/>.
		/// </summary>
		/// <param name="newSize">The new size of the buffer.</param>
		/// <exception cref="ArgumentOutOfRangeException">The <paramref name="newSize"/> argument is not a positive integer.</exception>
		public void Resize(int newSize) 
		{
			lock(this)
			{
				if (newSize < 0) 
				{
					throw new ArgumentOutOfRangeException("Parameter: newSize, Value: [" + newSize + "] out of range. Non zero positive integer required");
				}
				if (newSize == m_numElems)
				{
					return; // nothing to do
				}
	
				LoggingEvent[] temp = new  LoggingEvent[newSize];

				int loopLen = (newSize < m_numElems) ? newSize : m_numElems;
	
				for(int i = 0; i < loopLen; i++) 
				{
					temp[i] = m_ea[m_first];
					m_ea[m_first] = null;

					if (++m_first == m_numElems) 
					{
						m_first = 0;
					}
				}

				m_ea = temp;
				m_first = 0;
				m_numElems = loopLen;
				m_maxSize = newSize;

				if (loopLen == newSize) 
				{
					m_last = 0;
				} 
				else 
				{
					m_last = loopLen;
				}
			}
		}
		/// <summary>
		/// Pops all the logging events from the buffer into an array.
		/// </summary>
		/// <returns>An array of all the logging events in the buffer.</returns>
		public LoggingEvent[] PopAll()
		{
			lock(this)
			{
				LoggingEvent[] ret = new LoggingEvent[m_numElems];

				if (m_numElems > 0)
				{
					if (m_first < m_last)
					{
						Array.Copy(m_ea, m_first, ret, 0, m_numElems);
					}
					else
					{
						Array.Copy(m_ea, m_first, ret, 0, m_maxSize - m_first);
						Array.Copy(m_ea, 0, ret, m_maxSize - m_first, m_last);
					}
				}

				// Set all the elements to null
				Array.Clear(m_ea, 0, m_ea.Length);

				m_first = 0;
				m_last = 0;
				m_numElems = 0;

				return ret;
			}
		}
			/// <summary>
			/// Convert the pattern to the rendered message
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the precision of the fully qualified name specified</returns>
			override protected string Convert(LoggingEvent loggingEvent) 
			{
				string n = GetFullyQualifiedName(loggingEvent);
				if (m_precision <= 0)
				{
					return n;
				}
				else 
				{
					int len = n.Length;

					// We subtract 1 from 'len' when assigning to 'end' to avoid out of
					// bounds exception in return r.substring(end+1, len). This can happen if
					// precision is 1 and the logger name ends with a dot. 
					int end = len -1 ;
					for(int i = m_precision; i > 0; i--) 
					{	  
						end = n.LastIndexOf('.', end-1);
						if (end == -1)
						{
							return n;
						}
					}
					return n.Substring(end+1, len-end-1);
				}	  
			}
			/// <summary>
			/// Override the formatting behaviour to ignore the FormattingInfo
			/// because we have a literal instead.
			/// </summary>
			/// <param name="buffer">the builder to write to</param>
			/// <param name="loggingEvent">the event being logged</param>
			override public void Format(StringBuilder buffer, LoggingEvent loggingEvent) 
			{
				buffer.Append(m_literal);
			}
			/// <summary>
			/// Gets the fully qualified name of the class
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the class name</returns>
			override protected string GetFullyQualifiedName(LoggingEvent loggingEvent) 
			{
				return loggingEvent.LocationInformation.ClassName;
			}
			/// <summary>
			/// Convert this pattern into the rendered message
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the literal</returns>
			override protected string Convert(LoggingEvent loggingEvent) 
			{
				return m_literal;
			}
		/// <summary>
		/// Check if this filter should allow the event to be logged
		/// </summary>
		/// <remarks>
		/// The rendered message is matched against the <see cref="StringToMatch"/>.
		/// If the <see cref="StringToMatch"/> occurs as a substring within
		/// the message then a match will have occurred. If no match occurs
		/// this function will return <see cref="FilterDecision.NEUTRAL"/>
		/// allowing other filters to check the event. If a match occurs then
		/// the value of <see cref="AcceptOnMatch"/> is checked. If it is
		/// true then <see cref="FilterDecision.ACCEPT"/> is returned otherwise
		/// <see cref="FilterDecision.DENY"/> is returned.
		/// </remarks>
		/// <param name="loggingEvent">the event being logged</param>
		/// <returns>see remarks</returns>
		override public FilterDecision Decide(LoggingEvent loggingEvent) 
		{
			if (loggingEvent == null)
			{
				throw new ArgumentNullException("loggingEvent");
			}

			string msg = loggingEvent.RenderedMessage;

			// Check if we have been setup to filter
			if (msg == null || (m_stringToMatch == null && m_regexToMatch == null))
			{
				// We cannot filter so allow the filter chain
				// to continue processing
				return FilterDecision.NEUTRAL;
			}
    
			// Firstly check if we are matching using a regex
			if (m_regexToMatch != null)
			{
				// Check the regex
				if (m_regexToMatch.Match(msg).Success == false)
				{
					// No match, continue processing
					return FilterDecision.NEUTRAL;
				} 

				// we've got a match
				if (m_acceptOnMatch) 
				{
					return FilterDecision.ACCEPT;
				} 
				return FilterDecision.DENY;
			}
			else if (m_stringToMatch != null)
			{
				// Check substring match
				if (msg.IndexOf(m_stringToMatch) == -1) 
				{
					// No match, continue processing
					return FilterDecision.NEUTRAL;
				} 

				// we've got a match
				if (m_acceptOnMatch) 
				{
					return FilterDecision.ACCEPT;
				} 
				return FilterDecision.DENY;
			}
			return FilterDecision.NEUTRAL;

		}
		/// <summary>
		/// Sends the contents of the cyclic buffer as an e-mail message.
		/// </summary>
		/// <param name="events">The logging events to send.</param>
		override protected void SendBuffer(LoggingEvent[] events) 
		{
			// Note: this code already owns the monitor for this
			// appender. This frees us from needing to synchronize on 'cb'.
			try 
			{	  
				StringBuilder sbuf = new StringBuilder();

				string t = Layout.Header;
				if (t != null)
				{
					sbuf.Append(t);
				}


				string hostName = SystemInfo.HostName;

				for(int i = 0; i < events.Length; i++) 
				{
					// Set the hostname property
					if (events[i].Properties[LoggingEvent.HostNameProperty] == null)
					{
						events[i].Properties[LoggingEvent.HostNameProperty] = hostName;
					}

					// Render the event and append the text to the buffer
					sbuf.Append(RenderLoggingEvent(events[i]));
				}

				t = Layout.Footer;
				if (t != null)
				{
					sbuf.Append(t);
				}

				MailMessage mailMessage = new MailMessage();
				mailMessage.Body = sbuf.ToString();
				mailMessage.From = m_from;
				mailMessage.To = m_to;
				mailMessage.Subject = m_subject;

				if (m_smtpHost != null && m_smtpHost.Length > 0)
				{
					SmtpMail.SmtpServer = m_smtpHost;
				}

				SmtpMail.Send(mailMessage);
			} 
			catch(Exception e) 
			{
				ErrorHandler.Error("Error occurred while sending e-mail notification.", e);
			}
		}
 /// <summary>
 /// The format.
 /// </summary>
 /// <param name="loggingEvent">
 /// The logging event.
 /// </param>
 /// <returns>
 /// The <see cref="string"/>.
 /// </returns>
 public string Format(LoggingEvent loggingEvent)
 {
     return this.InnerLayout.Format(loggingEvent);
 }
			/// <summary>
			/// To the conversion
			/// </summary>
			/// <param name="loggingEvent">the event being logged</param>
			/// <returns>the result of converting the pattern</returns>
			override protected string Convert(LoggingEvent loggingEvent) 
			{
				switch(m_type) 
				{
					case RELATIVE_TIME_CONVERTER: 
						return TimeDifferenceInMillis(LoggingEvent.StartTime, loggingEvent.TimeStamp).ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
					case THREAD_CONVERTER:
						return loggingEvent.ThreadName;
					case LEVEL_CONVERTER:
						return loggingEvent.Level.ToString();
					case NDC_CONVERTER:  
						return loggingEvent.NestedContext;
					case MESSAGE_CONVERTER: 
						return loggingEvent.RenderedMessage;
					case USERNAME_CONVERTER:
						return loggingEvent.UserName;
					case IDENTITY_CONVERTER:
						return loggingEvent.Identity;
					case APPDOMAIN_CONVERTER:
						return loggingEvent.Domain;

					default: 
						return null;
				}
			}