LocalSyslogAppender

Namespace: log4net
We found 10 examples in language CSharp for this search. You will see 45 fragments of code.
		public void AddMapping(LocalSyslogAppender.LevelSeverity mapping)
		{
			this.m_levelMapping.Add(mapping);
		}
		public override void ActivateOptions()
		{
			base.ActivateOptions();
			this.m_levelMapping.ActivateOptions();
			string text = this.m_identity;
			if (text == null)
			{
				text = SystemInfo.ApplicationFriendlyName;
			}
			this.m_handleToIdentity = Marshal.StringToHGlobalAnsi(text);
			LocalSyslogAppender.openlog(this.m_handleToIdentity, 1, this.m_facility);
		}
		protected override void Append(LoggingEvent loggingEvent)
		{
			int priority = LocalSyslogAppender.GeneratePriority(this.m_facility, this.GetSeverity(loggingEvent.Level));
			string message = base.RenderLoggingEvent(loggingEvent);
			LocalSyslogAppender.syslog(priority, "%s", message);
		}
		protected override void OnClose()
		{
			base.OnClose();
			try
			{
				LocalSyslogAppender.closelog();
			}
			catch (DllNotFoundException)
			{
			}
			if (this.m_handleToIdentity != IntPtr.Zero)
			{
				Marshal.FreeHGlobal(this.m_handleToIdentity);
			}
		}
		private static int GeneratePriority(LocalSyslogAppender.SyslogFacility facility, LocalSyslogAppender.SyslogSeverity severity)
		{
			return (int)(facility * LocalSyslogAppender.SyslogFacility.Uucp + (int)severity);
		}
		[DllImport("libc")]
		private static extern void openlog(IntPtr ident, int option, LocalSyslogAppender.SyslogFacility facility);


        public virtual long Map(Level log4NetLevel)
        {
            if (log4NetLevel == null) return (long)LocalSyslogAppender.SyslogSeverity.Debug;
            var mappedValue = (long)LocalSyslogAppender.SyslogSeverity.Debug;
            levelMappings.TryGetValue(log4NetLevel.Name, out mappedValue);
            return mappedValue;
        }


		/// <summary>
		/// Add a mapping of level to severity
		/// </summary>
		/// <param name="mapping">The mapping to add</param>
		/// <remarks>
		/// <para>
		/// Adds a <see cref="T:log4net.Appender.LocalSyslogAppender.LevelSeverity" /> to this appender.
		/// </para>
		/// </remarks>
		public void AddMapping(LevelSeverity mapping)
		{
			m_levelMapping.Add(mapping);
		}

		/// <summary>
		/// Initialize the appender based on the options set.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This is part of the <see cref="T:log4net.Core.IOptionHandler" /> delayed object
		/// activation scheme. The <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions" /> method must 
		/// be called on this object after the configuration properties have
		/// been set. Until <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions" /> is called this
		/// object is in an undefined state and must not be used. 
		/// </para>
		/// <para>
		/// If any of the configuration properties are modified then 
		/// <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions" /> must be called again.
		/// </para>
		/// </remarks>
		[SecuritySafeCritical]
		public override void ActivateOptions()
		{
			base.ActivateOptions();
			m_levelMapping.ActivateOptions();
			string text = m_identity;
			if (text == null)
			{
				text = SystemInfo.ApplicationFriendlyName;
			}
			m_handleToIdentity = Marshal.StringToHGlobalAnsi(text);
			openlog(m_handleToIdentity, 1, m_facility);
		}

		/// <summary>
		/// This method is called by the <see cref="M:AppenderSkeleton.DoAppend(LoggingEvent)" /> method.
		/// </summary>
		/// <param name="loggingEvent">The event to log.</param>
		/// <remarks>
		/// <para>
		/// Writes the event to a remote syslog daemon.
		/// </para>
		/// <para>
		/// The format of the output will depend on the appender's layout.
		/// </para>
		/// </remarks>
		[SecuritySafeCritical]
		protected override void Append(LoggingEvent loggingEvent)
		{
			int priority = GeneratePriority(m_facility, GetSeverity(loggingEvent.Level));
			string message = RenderLoggingEvent(loggingEvent);
			syslog(priority, "%s", message);
		}

		/// <summary>
		/// Close the syslog when the appender is closed
		/// </summary>
		/// <remarks>
		/// <para>
		/// Close the syslog when the appender is closed
		/// </para>
		/// </remarks>
		[SecuritySafeCritical]
		protected override void OnClose()
		{
			base.OnClose();
			try
			{
				closelog();
			}
			catch (DllNotFoundException)
			{
			}
			if (m_handleToIdentity != IntPtr.Zero)
			{
				Marshal.FreeHGlobal(m_handleToIdentity);
			}
		}

		/// <summary>
		/// Translates a log4net level to a syslog severity.
		/// </summary>
		/// <param name="level">A log4net level.</param>
		/// <returns>A syslog severity.</returns>
		/// <remarks>
		/// <para>
		/// Translates a log4net level to a syslog severity.
		/// </para>
		/// </remarks>
		protected virtual SyslogSeverity GetSeverity(Level level)
		{
			LevelSeverity levelSeverity = m_levelMapping.Lookup(level) as LevelSeverity;
			if (levelSeverity != null)
			{
				return levelSeverity.Severity;
			}
			if (level >= Level.Alert)
			{
				return SyslogSeverity.Alert;
			}
			if (level >= Level.Critical)
			{
				return SyslogSeverity.Critical;
			}
			if (level >= Level.Error)
			{
				return SyslogSeverity.Error;
			}
			if (level >= Level.Warn)
			{
				return SyslogSeverity.Warning;
			}
			if (level >= Level.Notice)
			{
				return SyslogSeverity.Notice;
			}
			if (level >= Level.Info)
			{
				return SyslogSeverity.Informational;
			}
			return SyslogSeverity.Debug;
		}

		/// <summary>
		/// Generate a syslog priority.
		/// </summary>
		/// <param name="facility">The syslog facility.</param>
		/// <param name="severity">The syslog severity.</param>
		/// <returns>A syslog priority.</returns>
		private static int GeneratePriority(SyslogFacility facility, SyslogSeverity severity)
		{
			return (int)((int)facility * 8 + severity);
		}


        private Dictionary<string, object> ParseField(string value)
        {
            var innerAdditionalFields = new Dictionary<string, object>();

            if (value != null)
            {
                string[] fields;
                if (!string.IsNullOrEmpty(FieldSeparator))
                {
                    fields = value.Split(new[] { FieldSeparator }, StringSplitOptions.RemoveEmptyEntries);
                }
                else
                {
                    fields = value.Split(',');
                }

                if (!string.IsNullOrEmpty(KeyValueSeparator))
                {
                    innerAdditionalFields = fields
                        .Select(it => it.Split(new[] { KeyValueSeparator }, StringSplitOptions.RemoveEmptyEntries))
                        .ToDictionary(it => it[0], it => (object)it[1]);
                }
                else
                {
                    innerAdditionalFields = fields
                        .Select(it => it.Split(':'))
                        .ToDictionary(it => it[0], it => (object)it[1]);
                }
            }
            return innerAdditionalFields;
        }

        public override void Format(System.IO.TextWriter writer, LoggingEvent loggingEvent)
        {
            var gelfMessage = GetBaseGelfMessage(loggingEvent);

            AddLoggingEventToMessage(loggingEvent, gelfMessage);

            AddAdditionalFields(loggingEvent, gelfMessage);

            writer.Write(JsonConvert.SerializeObject(gelfMessage, Formatting.Indented));
        }

        private void AddLoggingEventToMessage(LoggingEvent loggingEvent, GelfMessage gelfMessage)
        {
            //If conversion pattern is specified then defer to PatterLayout for building the message body
            if (!string.IsNullOrWhiteSpace(ConversionPattern))
            {
                var message = GetValueFromPattern(loggingEvent, ConversionPattern);
                gelfMessage.FullMessage = message;
                gelfMessage.ShortMessage = message.TruncateMessage(SHORT_MESSAGE_LENGTH);
            }
            else //Otherwise do our custom message builder stuff
            {
                var messageObject = loggingEvent.MessageObject;
                if (messageObject == null)
                {
                    if (!string.IsNullOrEmpty(loggingEvent.RenderedMessage))
                    {
                        if (loggingEvent.RenderedMessage.ValidateJSON())
                        {
                            AddToMessage(gelfMessage, loggingEvent.RenderedMessage.ToJson().ToDictionary());
                        }

                        gelfMessage.FullMessage = !string.IsNullOrEmpty(gelfMessage.FullMessage) ? gelfMessage.FullMessage : loggingEvent.RenderedMessage;
                        gelfMessage.ShortMessage = !string.IsNullOrEmpty(gelfMessage.ShortMessage) ? gelfMessage.ShortMessage : gelfMessage.FullMessage.TruncateMessage(SHORT_MESSAGE_LENGTH);

                        return;
                    }
                    gelfMessage.FullMessage = SystemInfo.NullText;
                    gelfMessage.ShortMessage = SystemInfo.NullText;
                }

                if (messageObject is string || messageObject is SystemStringFormat)
                {
                    var fullMessage = messageObject.ToString();
                    gelfMessage.FullMessage = fullMessage;
                    gelfMessage.ShortMessage = fullMessage.TruncateMessage(SHORT_MESSAGE_LENGTH);
                }
                else if (messageObject is IDictionary)
                {
                    AddToMessage(gelfMessage, messageObject as IDictionary);
                }
                else
                {
                    AddToMessage(gelfMessage, messageObject.ToDictionary());
                }

                gelfMessage.FullMessage = !string.IsNullOrEmpty(gelfMessage.FullMessage) ? gelfMessage.FullMessage : messageObject.ToString();
                gelfMessage.ShortMessage = !string.IsNullOrEmpty(gelfMessage.ShortMessage) ? gelfMessage.ShortMessage : gelfMessage.FullMessage.TruncateMessage(SHORT_MESSAGE_LENGTH);
            }

            if (LogStackTraceFromMessage && loggingEvent.ExceptionObject != null)
            {
                gelfMessage.FullMessage = string.Format("{0} - {1}.", gelfMessage.FullMessage, loggingEvent.GetExceptionString());
            }
        }

        private GelfMessage GetBaseGelfMessage(LoggingEvent loggingEvent)
        {
            var message = new GelfMessage(SendTimeStampAsString)
            {
                Facility = Facility ?? "GELF",
                File = string.Empty,
                Host = HostName ?? Environment.MachineName,
                Level = GetSyslogSeverity(loggingEvent.Level),
                Line = string.Empty,
                TimeStamp = loggingEvent.TimeStamp,
                Version = GELF_VERSION,
            };

            message.Add("LoggerName", loggingEvent.LoggerName);

            if (this.IncludeLocationInformation)
            {
                message.File = (loggingEvent.LocationInformation.FileName != "?" ? loggingEvent.LocationInformation.FileName : string.Empty);
                message.Line = (loggingEvent.LocationInformation.LineNumber != "?" ? loggingEvent.LocationInformation.LineNumber : string.Empty);
            }

            return message;
        }

        private void AddToMessage(GelfMessage gelfMessage, IDictionary messageObject)
        {
            foreach (DictionaryEntry entry in messageObject as IDictionary)
            {
                var key = (entry.Key ?? string.Empty).ToString();
                var value = (entry.Value ?? string.Empty).ToString();
                if (FullMessageKeyValues.Contains(key, StringComparer.OrdinalIgnoreCase))
                    gelfMessage.FullMessage = value;
                else if (ShortMessageKeyValues.Contains(key, StringComparer.OrdinalIgnoreCase))
                    gelfMessage.ShortMessage = value.TruncateMessage(SHORT_MESSAGE_LENGTH);
                else
                {
                    key = key.StartsWith("_") ? key : "_" + key;
                    gelfMessage[key] = FormatAdditionalField(entry.Value);
                }
            }
        }

        private void AddAdditionalFields(LoggingEvent loggingEvent, GelfMessage message)
        {
            var additionalFields = ParseField(AdditionalFields) ?? new Dictionary<string, object>();
            foreach (DictionaryEntry item in loggingEvent.GetProperties())
            {
                var key = item.Key as string;
                if (key != null && !key.StartsWith("log4net:") /*exclude log4net built-in properties */ )
                {
                    additionalFields.Add(key, FormatAdditionalField(item.Value));
                }
            }

            foreach (var kvp in additionalFields)
            {
                var key = kvp.Key.StartsWith("_") ? kvp.Key : "_" + kvp.Key;

                //If the value starts with a '%' then defer to the pattern layout
                var patternValue = kvp.Value as string;
                var value = patternValue != null && patternValue.StartsWith("%") ? GetValueFromPattern(loggingEvent, patternValue) : kvp.Value;
                message[key] = value;
            }
        }


        protected override void AddAppenderSpecificProperties()
        {
            base.AddAppenderSpecificProperties();

            AddProperty(new EnumProperty<SyslogFacility>("Facility:", 110, Log4NetXmlConstants.Facility) { SelectedValue = SyslogFacility.User.ToString() });
            AddProperty(new StringValueProperty("Identity:", Log4NetXmlConstants.Identity));
        }



        private Dictionary<string, object> ParseField(string value)
        {
            var innerAdditionalFields = new Dictionary<string, object>();

            if (value != null)
            {
                string[] fields;
                if (!string.IsNullOrEmpty(FieldSeparator))
                {
                    fields = value.Split(new[] { FieldSeparator }, StringSplitOptions.RemoveEmptyEntries);
                }
                else
                {
                    fields = value.Split(',');
                }

                if (!string.IsNullOrEmpty(KeyValueSeparator))
                {
                    innerAdditionalFields = fields
                        .Select(it => it.Split(new[] { KeyValueSeparator }, StringSplitOptions.RemoveEmptyEntries))
                        .ToDictionary(it => it[0], it => (object)it[1]);

                }
                else
                {
                    innerAdditionalFields = fields
                        .Select(it => it.Split(':'))
                        .ToDictionary(it => it[0], it => (object)it[1]);
                }
            }
            return innerAdditionalFields;
        }

        public override void Format(System.IO.TextWriter writer, LoggingEvent loggingEvent)
        {
            var gelfMessage = GetBaseGelfMessage(loggingEvent);

            AddLoggingEventToMessage(loggingEvent, gelfMessage);

            AddAdditionalFields(loggingEvent, gelfMessage);

            writer.Write(JsonConvert.SerializeObject(gelfMessage, Formatting.Indented));
        }

        private void AddLoggingEventToMessage(LoggingEvent loggingEvent, GelfMessage gelfMessage)
        {
            //If conversion pattern is specified then defer to PatterLayout for building the message body
            if (!string.IsNullOrWhiteSpace(ConversionPattern))
            {
                var message = GetValueFromPattern(loggingEvent, ConversionPattern);
                gelfMessage.FullMessage = message;
                gelfMessage.ShortMessage = message.TruncateMessage(SHORT_MESSAGE_LENGTH);
            }
            else //Otherwise do our custom message builder stuff
            {
                var messageObject = loggingEvent.MessageObject;
                if (messageObject == null)
                {
                    if (!string.IsNullOrEmpty(loggingEvent.RenderedMessage))
                    {
                        if (loggingEvent.RenderedMessage.ValidateJSON())
                        {
                            AddToMessage(gelfMessage, loggingEvent.RenderedMessage.ToJson().ToDictionary());
                        }

                        gelfMessage.FullMessage = !string.IsNullOrEmpty(gelfMessage.FullMessage) ? gelfMessage.FullMessage : loggingEvent.RenderedMessage;
                        gelfMessage.ShortMessage = !string.IsNullOrEmpty(gelfMessage.ShortMessage) ? gelfMessage.ShortMessage : gelfMessage.FullMessage.TruncateMessage(SHORT_MESSAGE_LENGTH);

                        return;
                    }
                    gelfMessage.FullMessage = SystemInfo.NullText;
                    gelfMessage.ShortMessage = SystemInfo.NullText;
                }

                if (messageObject is string || messageObject is SystemStringFormat)
                {
                    var fullMessage = messageObject.ToString();
                    gelfMessage.FullMessage = fullMessage;
                    gelfMessage.ShortMessage = fullMessage.TruncateMessage(SHORT_MESSAGE_LENGTH);
                }
                else if (messageObject is IDictionary)
                {
                    AddToMessage(gelfMessage, messageObject as IDictionary);
                }
                else
                {
                    AddToMessage(gelfMessage, messageObject.ToDictionary());
                }

                gelfMessage.FullMessage = !string.IsNullOrEmpty(gelfMessage.FullMessage) ? gelfMessage.FullMessage : messageObject.ToString();
                gelfMessage.ShortMessage = !string.IsNullOrEmpty(gelfMessage.ShortMessage) ? gelfMessage.ShortMessage : gelfMessage.FullMessage.TruncateMessage(SHORT_MESSAGE_LENGTH);
            }

            if (LogStackTraceFromMessage && loggingEvent.ExceptionObject != null)
            {
                gelfMessage.FullMessage = string.Format("{0} - {1}.", gelfMessage.FullMessage, loggingEvent.GetExceptionString());
            }
        }

        private GelfMessage GetBaseGelfMessage(LoggingEvent loggingEvent)
        {
            var message = new GelfMessage
            {
                Facility = Facility ?? "GELF",
                File = string.Empty,
                Host = HostName ?? Environment.MachineName,
                Level = GetSyslogSeverity(loggingEvent.Level),
                Line = string.Empty,
                TimeStamp = loggingEvent.TimeStamp,
                Version = GELF_VERSION,
            };

            message.Add("LoggerName", loggingEvent.LoggerName);

            if (this.IncludeLocationInformation)
            {
                message.File = loggingEvent.LocationInformation.FileName;
                message.Line = loggingEvent.LocationInformation.LineNumber;
            }

            return message;
        }

        private void AddToMessage(GelfMessage gelfMessage, IDictionary messageObject)
        {
            foreach (DictionaryEntry entry in messageObject as IDictionary)
            {
                var key = (entry.Key ?? string.Empty).ToString();
                var value = (entry.Value ?? string.Empty).ToString();
                if (FullMessageKeyValues.Contains(key, StringComparer.OrdinalIgnoreCase))
                    gelfMessage.FullMessage = value;
                else if (ShortMessageKeyValues.Contains(key, StringComparer.OrdinalIgnoreCase))
                    gelfMessage.ShortMessage = value.TruncateMessage(SHORT_MESSAGE_LENGTH);
                else
                {
                    key = key.StartsWith("_") ? key : "_" + key;
                    gelfMessage[key] = FormatAdditionalField(entry.Value);
                }
            }
        }

        private void AddAdditionalFields(LoggingEvent loggingEvent, GelfMessage message)
        {
            var additionalFields = ParseField(AdditionalFields) ?? new Dictionary<string, object>();
            foreach (DictionaryEntry item in loggingEvent.GetProperties())
            {
                var key = item.Key as string;
                if (key != null && !key.StartsWith("log4net:") /*exclude log4net built-in properties */ )
                {
                    additionalFields.Add(key, FormatAdditionalField(item.Value));
                }
            }

            foreach (var kvp in additionalFields)
            {
                var key = kvp.Key.StartsWith("_") ? kvp.Key : "_" + kvp.Key;

                //If the value starts with a '%' then defer to the pattern layout
                var patternValue = kvp.Value as string;
                var value = patternValue != null && patternValue.StartsWith("%") ? GetValueFromPattern(loggingEvent, patternValue) : kvp.Value;
                message[key] = value;
            }
        }



        private Dictionary<string, object> ParseField(string value)
        {
            var innerAdditionalFields= new Dictionary<string, object>();

            if (value != null)
            {
                string[] fields;
                if (!string.IsNullOrEmpty(FieldSeparator))
                {
                    fields = value.Split(new[] {FieldSeparator}, StringSplitOptions.RemoveEmptyEntries);
                }
                else
                {
                    fields = value.Split(',');
                }

                if (!string.IsNullOrEmpty(KeyValueSeparator))
                {
                    innerAdditionalFields = fields
                        .Select(it => it.Split(new[] {KeyValueSeparator}, StringSplitOptions.RemoveEmptyEntries))
                        .ToDictionary(it => it[0], it => (object) it[1]);

                }
                else
                {
                    innerAdditionalFields = fields
                        .Select(it => it.Split(':'))
                        .ToDictionary(it => it[0], it => (object) it[1]);
                }
            }
            return innerAdditionalFields;
        }

        public override void Format(System.IO.TextWriter writer, LoggingEvent loggingEvent)
        {
            var gelfMessage = GetBaseGelfMessage(loggingEvent);

            AddLoggingEventToMessage(loggingEvent, gelfMessage);

            AddAdditionalFields(loggingEvent, gelfMessage);

            writer.Write(JsonConvert.SerializeObject(gelfMessage, Formatting.Indented));
        }

        private void AddLoggingEventToMessage(LoggingEvent loggingEvent, GelfMessage gelfMessage)
        {
            //If conversion pattern is specified then defer to PatterLayout for building the message body
            if (!string.IsNullOrWhiteSpace(ConversionPattern))
            {
                var message = GetValueFromPattern(loggingEvent, ConversionPattern);
                gelfMessage.FullMessage = message;
                gelfMessage.ShortMessage = message.TruncateMessage(SHORT_MESSAGE_LENGTH);
            }
            else //Otherwise do our custom message builder stuff
            {
                var messageObject = loggingEvent.MessageObject;
                if (messageObject == null)
                {
                    gelfMessage.FullMessage = SystemInfo.NullText;
                    gelfMessage.ShortMessage = SystemInfo.NullText;
                }

                if (messageObject is string || messageObject is SystemStringFormat)
                {
                    var fullMessage = messageObject.ToString();
                    gelfMessage.FullMessage = fullMessage;
                    gelfMessage.ShortMessage = fullMessage.TruncateMessage(SHORT_MESSAGE_LENGTH);
                }
                else if (messageObject is IDictionary)
                {
                    AddToMessage(gelfMessage, messageObject as IDictionary);
                }
                else
                {
                    AddToMessage(gelfMessage, messageObject.ToDictionary());
                }

                gelfMessage.FullMessage = !string.IsNullOrEmpty(gelfMessage.FullMessage) ? gelfMessage.FullMessage :  messageObject.ToString();
                gelfMessage.ShortMessage = !string.IsNullOrEmpty(gelfMessage.ShortMessage) ? gelfMessage.ShortMessage : gelfMessage.FullMessage.TruncateMessage(SHORT_MESSAGE_LENGTH);
            }

            if (LogStackTraceFromMessage && loggingEvent.ExceptionObject != null)
            {
                gelfMessage.FullMessage = string.Format("{0} - {1}.", gelfMessage.FullMessage, loggingEvent.GetExceptionString());
            }
        }

        private GelfMessage GetBaseGelfMessage(LoggingEvent loggingEvent)
        {
            var message = new GelfMessage
            {
                Facility = Facility ?? "GELF",
                File = string.Empty,
                Host = HostName ?? Environment.MachineName,
                Level = GetSyslogSeverity(loggingEvent.Level),
                Line = string.Empty,
                TimeStamp = loggingEvent.TimeStamp,
                Version = GELF_VERSION,
            };

            message.Add("LoggerName", loggingEvent.LoggerName);

            if (this.IncludeLocationInformation)
            {
                message.File = loggingEvent.LocationInformation.FileName;
                message.Line = loggingEvent.LocationInformation.LineNumber;
            }

            return message;
        }

        private void AddToMessage(GelfMessage gelfMessage, IDictionary messageObject)
        {
            foreach (DictionaryEntry entry in messageObject as IDictionary)
            {
                var key = (entry.Key ?? string.Empty).ToString();
                var value = (entry.Value ?? string.Empty).ToString();
                if (FullMessageKeyValues.Contains(key, StringComparer.OrdinalIgnoreCase))
                    gelfMessage.FullMessage = value;
                else if (ShortMessageKeyValues.Contains(key, StringComparer.OrdinalIgnoreCase))
                    gelfMessage.ShortMessage = value.TruncateMessage(SHORT_MESSAGE_LENGTH);
                else
                {
                    key = key.StartsWith("_") ? key : "_" + key;
                    gelfMessage[key] = FormatAdditionalField(entry.Value);
                }
            }
        }

        private void AddAdditionalFields(LoggingEvent loggingEvent, GelfMessage message)
        {
            var additionalFields = ParseField(AdditionalFields)??new Dictionary<string, object>();
            foreach (DictionaryEntry item in loggingEvent.GetProperties())
            {
                var key = item.Key as string;
                if (key != null && !key.StartsWith("log4net:") /*exclude log4net built-in properties */ )
                {
                    additionalFields.Add(key, FormatAdditionalField(item.Value));
                }
            }

            foreach (var kvp in additionalFields)
            {
                var key = kvp.Key.StartsWith("_") ? kvp.Key : "_" + kvp.Key;

                //If the value starts with a '%' then defer to the pattern layout
                var patternValue = kvp.Value as string;
                var value = patternValue != null && patternValue.StartsWith("%") ? GetValueFromPattern(loggingEvent, patternValue) : kvp.Value;
                message[key] = value;
            }
        }


        [SetUp]
        public void SetUp()
        {
            XmlDocument xmlDoc = new XmlDocument();
            XmlElement log4NetNode = xmlDoc.CreateElement("log4net");

            IElementConfiguration configuration = Substitute.For<IElementConfiguration>();
            configuration.ConfigXml.Returns(xmlDoc);
            configuration.Log4NetNode.Returns(log4NetNode);

            mSut = new LocalSyslogAppender(configuration);
        }

        [Test]
        public void Name_ShouldReturnCorrectValue()
        {
            Assert.AreEqual("Local Syslog Appender", mSut.Name);
        }

        [Test]
        public void Icon_ShouldReturnCorrectValue()
        {
            Assert.AreEqual("pack://application:,,,/Editor;component/Images/list-add.png", mSut.Icon);
        }

        [Test]
        public void Descriptor_ShouldReturnCorrectValue()
        {
            Assert.AreEqual(AppenderDescriptor.LocalSyslog, mSut.Descriptor);
        }

        [Test]
        public void Initialize_ShouldAddDefaultProperties()
        {
            mSut.Initialize();

            TestHelpers.AssertAppenderSkeletonPropertiesExist(mSut.Properties);
        }

        [Test]
        public void Initialize_ShouldAddLocalSyslogProperties()
        {
            mSut.Initialize();

            mSut.Properties.Single(p => p.GetType() == typeof(EnumProperty<SyslogFacility>));
            mSut.Properties.Single(p => p.GetType() == typeof(StringValueProperty) && ((StringValueProperty)p).Name == "Identity:");
        }

//#region Copyright & License
///*
// * Copyright 2004-2006 The Apache Software Foundation
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//#endregion

//// .NET Compact Framework 1.0 has no support for Marshal.StringToHGlobalAnsi
//// SSCLI 1.0 has no support for Marshal.StringToHGlobalAnsi
//#if !NETCF && !SSCLI

//using System;
//using System.Runtime.InteropServices;

//using log4net.Core;
//using log4net.Appender;
//using log4net.Util;
//using log4net.Layout;

//namespace log4net.Appender 
//{
//  /// <summary>
//  /// Logs events to a local syslog service.
//  /// </summary>
//  /// <remarks>
//  /// <note>
//  /// This appender uses the POSIX libc library functions <c>openlog</c>, <c>syslog</c>, and <c>closelog</c>.
//  /// If these functions are not available on the local system then this appender will not work!
//  /// </note>
//  /// <para>
//  /// The functions <c>openlog</c>, <c>syslog</c>, and <c>closelog</c> are specified in SUSv2 and 
//  /// POSIX 1003.1-2001 standards. These are used to log messages to the local syslog service.
//  /// </para>
//  /// <para>
//  /// This appender talks to a local syslog service. If you need to log to a remote syslog
//  /// daemon and you cannot configure your local syslog service to do this you may be
//  /// able to use the <see cref="RemoteSyslogAppender"/> to log via UDP.
//  /// </para>
//  /// <para>
//  /// Syslog messages must have a facility and and a severity. The severity
//  /// is derived from the Level of the logging event.
//  /// The facility must be chosen from the set of defined syslog 
//  /// <see cref="SyslogFacility"/> values. The facilities list is predefined
//  /// and cannot be extended.
//  /// </para>
//  /// <para>
//  /// An identifier is specified with each log message. This can be specified
//  /// by setting the <see cref="Identity"/> property. The identity (also know 
//  /// as the tag) must not contain white space. The default value for the
//  /// identity is the application name (from <see cref="SystemInfo.ApplicationFriendlyName"/>).
//  /// </para>
//  /// </remarks>
//  /// <author>Rob Lyon</author>
//  /// <author>Nicko Cadell</author>
//  public class LocalSyslogAppender : AppenderSkeleton 
//  {
//    #region Enumerations

//    /// <summary>
//    /// syslog severities
//    /// </summary>
//    /// <remarks>
//    /// <para>
//    /// The log4net Level maps to a syslog severity using the
//    /// <see cref="LocalSyslogAppender.AddMapping"/> method and the <see cref="LevelSeverity"/>
//    /// class. The severity is set on <see cref="LevelSeverity.Severity"/>.
//    /// </para>
//    /// </remarks>
//    public enum SyslogSeverity
//    {
//      /// <summary>
//      /// system is unusable
//      /// </summary>
//      Emergency = 0,

//      /// <summary>
//      /// action must be taken immediately
//      /// </summary>
//      Alert = 1,

//      /// <summary>
//      /// critical conditions
//      /// </summary>
//      Critical = 2,

//      /// <summary>
//      /// error conditions
//      /// </summary>
//      Error = 3,

//      /// <summary>
//      /// warning conditions
//      /// </summary>
//      Warning = 4,

//      /// <summary>
//      /// normal but significant condition
//      /// </summary>
//      Notice = 5,

//      /// <summary>
//      /// informational
//      /// </summary>
//      Informational = 6,

//      /// <summary>
//      /// debug-level messages
//      /// </summary>
//      Debug = 7
//    };

//    /// <summary>
//    /// syslog facilities
//    /// </summary>
//    /// <remarks>
//    /// <para>
//    /// The syslog facility defines which subsystem the logging comes from.
//    /// This is set on the <see cref="Facility"/> property.
//    /// </para>
//    /// </remarks>
//    public enum SyslogFacility
//    {
//      /// <summary>
//      /// kernel messages
//      /// </summary>
//      Kernel = 0,

//      /// <summary>
//      /// random user-level messages
//      /// </summary>
//      User = 1,

//      /// <summary>
//      /// mail system
//      /// </summary>
//      Mail = 2,

//      /// <summary>
//      /// system daemons
//      /// </summary>
//      Daemons = 3,

//      /// <summary>
//      /// security/authorization messages
//      /// </summary>
//      Authorization = 4,

//      /// <summary>
//      /// messages generated internally by syslogd
//      /// </summary>
//      Syslog = 5,

//      /// <summary>
//      /// line printer subsystem
//      /// </summary>
//      Printer = 6,

//      /// <summary>
//      /// network news subsystem
//      /// </summary>
//      News = 7,

//      /// <summary>
//      /// UUCP subsystem
//      /// </summary>
//      Uucp = 8,

//      /// <summary>
//      /// clock (cron/at) daemon
//      /// </summary>
//      Clock = 9,

//      /// <summary>
//      /// security/authorization  messages (private)
//      /// </summary>
//      Authorization2 = 10,

//      /// <summary>
//      /// ftp daemon
//      /// </summary>
//      Ftp = 11,

//      /// <summary>
//      /// NTP subsystem
//      /// </summary>
//      Ntp = 12,

//      /// <summary>
//      /// log audit
//      /// </summary>
//      Audit = 13,

//      /// <summary>
//      /// log alert
//      /// </summary>
//      Alert = 14,

//      /// <summary>
//      /// clock daemon
//      /// </summary>
//      Clock2 = 15,

//      /// <summary>
//      /// reserved for local use
//      /// </summary>
//      Local0 = 16,

//      /// <summary>
//      /// reserved for local use
//      /// </summary>
//      Local1 = 17,

//      /// <summary>
//      /// reserved for local use
//      /// </summary>
//      Local2 = 18,

//      /// <summary>
//      /// reserved for local use
//      /// </summary>
//      Local3 = 19,

//      /// <summary>
//      /// reserved for local use
//      /// </summary>
//      Local4 = 20,

//      /// <summary>
//      /// reserved for local use
//      /// </summary>
//      Local5 = 21,

//      /// <summary>
//      /// reserved for local use
//      /// </summary>
//      Local6 = 22,

//      /// <summary>
//      /// reserved for local use
//      /// </summary>
//      Local7 = 23
//    }

//    #endregion // Enumerations

//    #region Public Instance Constructors

//    /// <summary>
//    /// Initializes a new instance of the <see cref="LocalSyslogAppender" /> class.
//    /// </summary>
//    /// <remarks>
//    /// This instance of the <see cref="LocalSyslogAppender" /> class is set up to write 
//    /// to a local syslog service.
//    /// </remarks>
//    public LocalSyslogAppender() 
//    {
//    }

//    #endregion // Public Instance Constructors

//    #region Public Instance Properties
		
//    /// <summary>
//    /// Message identity
//    /// </summary>
//    /// <remarks>
//    /// <para>
//    /// An identifier is specified with each log message. This can be specified
//    /// by setting the <see cref="Identity"/> property. The identity (also know 
//    /// as the tag) must not contain white space. The default value for the
//    /// identity is the application name (from <see cref="SystemInfo.ApplicationFriendlyName"/>).
//    /// </para>
//    /// </remarks>
//    public string Identity
//    {
//      get { return m_identity; }
//      set { m_identity = value; }
//    }

//    /// <summary>
//    /// Syslog facility
//    /// </summary>
//    /// <remarks>
//    /// Set to one of the <see cref="SyslogFacility"/> values. The list of
//    /// facilities is predefined and cannot be extended. The default value
//    /// is <see cref="SyslogFacility.User"/>.
//    /// </remarks>
//    public SyslogFacility Facility
//    {
//      get { return m_facility; }
//      set { m_facility = value; }
//    }
		
//    #endregion // Public Instance Properties

//    /// <summary>
//    /// Add a mapping of level to severity
//    /// </summary>
//    /// <param name="mapping">The mapping to add</param>
//    /// <remarks>
//    /// <para>
//    /// Adds a <see cref="LevelSeverity"/> to this appender.
//    /// </para>
//    /// </remarks>
//    public void AddMapping(LevelSeverity mapping)
//    {
//      m_levelMapping.Add(mapping);
//    }

//    #region IOptionHandler Implementation

//    /// <summary>
//    /// Initialize the appender based on the options set.
//    /// </summary>
//    /// <remarks>
//    /// <para>
//    /// This is part of the <see cref="IOptionHandler"/> delayed object
//    /// activation scheme. The <see cref="ActivateOptions"/> method must 
//    /// be called on this object after the configuration properties have
//    /// been set. Until <see cref="ActivateOptions"/> is called this
//    /// object is in an undefined state and must not be used. 
//    /// </para>
//    /// <para>
//    /// If any of the configuration properties are modified then 
//    /// <see cref="ActivateOptions"/> must be called again.
//    /// </para>
//    /// </remarks>
//    public override void ActivateOptions()
//    {
//      base.ActivateOptions();
			
//      m_levelMapping.ActivateOptions();

//      string identString = m_identity;
//      if (identString == null)
//      {
//        // Set to app name by default
//        identString = SystemInfo.ApplicationFriendlyName;
//      }

//      // create the native heap ansi string. Note this is a copy of our string
//      // so we do not need to hold on to the string itself, holding on to the
//      // handle will keep the heap ansi string alive.
//      m_handleToIdentity = Marshal.StringToHGlobalAnsi(identString);

//      // open syslog
//      openlog(m_handleToIdentity, 1, m_facility);
//    }

//    #endregion // IOptionHandler Implementation

//    #region AppenderSkeleton Implementation

//    /// <summary>
//    /// This method is called by the <see cref="AppenderSkeleton.DoAppend(LoggingEvent)"/> method.
//    /// </summary>
//    /// <param name="loggingEvent">The event to log.</param>
//    /// <remarks>
//    /// <para>
//    /// Writes the event to a remote syslog daemon.
//    /// </para>
//    /// <para>
//    /// The format of the output will depend on the appender's layout.
//    /// </para>
//    /// </remarks>
//    protected override void Append(LoggingEvent loggingEvent) 
//    {
//      int priority = GeneratePriority(m_facility, GetSeverity(loggingEvent.Level));
//      string message = RenderLoggingEvent(loggingEvent);

//      // Call the local libc syslog method
//      // The second argument is a printf style format string
//      syslog(priority, "%s", message);
//    }

//    /// <summary>
//    /// Close the syslog when the appender is closed
//    /// </summary>
//    /// <remarks>
//    /// <para>
//    /// Close the syslog when the appender is closed
//    /// </para>
//    /// </remarks>
//    protected override void OnClose()
//    {
//      base.OnClose();

//      try
//      {
//        // close syslog
//        closelog();
//      }
//      catch(DllNotFoundException)
//      {
//        // Ignore dll not found at this point
//      }
		
//      if (m_handleToIdentity != IntPtr.Zero)
//      {
//        // free global ident
//        Marshal.FreeHGlobal(m_handleToIdentity);
//      }
//    }

//    /// <summary>
//    /// This appender requires a <see cref="AppenderSkeleton.Layout"/> to be set.
//    /// </summary>
//    /// <value><c>true</c></value>
//    /// <remarks>
//    /// <para>
//    /// This appender requires a <see cref="AppenderSkeleton.Layout"/> to be set.
//    /// </para>
//    /// </remarks>
//    override protected bool RequiresLayout
//    {
//      get { return true; }
//    }

//    #endregion // AppenderSkeleton Implementation

//    #region Protected Members

//    /// <summary>
//    /// Translates a log4net level to a syslog severity.
//    /// </summary>
//    /// <param name="level">A log4net level.</param>
//    /// <returns>A syslog severity.</returns>
//    /// <remarks>
//    /// <para>
//    /// Translates a log4net level to a syslog severity.
//    /// </para>
//    /// </remarks>
//    virtual protected SyslogSeverity GetSeverity(Level level)
//    {
//      LevelSeverity levelSeverity = m_levelMapping.Lookup(level) as LevelSeverity;
//      if (levelSeverity != null)
//      {
//        return levelSeverity.Severity;
//      }

//      //
//      // Fallback to sensible default values
//      //

//      if (level >= Level.Alert) 
//      {
//        return SyslogSeverity.Alert;
//      } 
//      else if (level >= Level.Critical) 
//      {
//        return SyslogSeverity.Critical;
//      } 
//      else if (level >= Level.Error) 
//      {
//        return SyslogSeverity.Error;
//      } 
//      else if (level >= Level.Warn) 
//      {
//        return SyslogSeverity.Warning;
//      } 
//      else if (level >= Level.Notice) 
//      {
//        return SyslogSeverity.Notice;
//      } 
//      else if (level >= Level.Info) 
//      {
//        return SyslogSeverity.Informational;
//      } 
//      // Default setting
//      return SyslogSeverity.Debug;
//    }

//    #endregion // Protected Members

//    #region Public Static Members

//    /// <summary>
//    /// Generate a syslog priority.
//    /// </summary>
//    /// <param name="facility">The syslog facility.</param>
//    /// <param name="severity">The syslog severity.</param>
//    /// <returns>A syslog priority.</returns>
//    private static int GeneratePriority(SyslogFacility facility, SyslogSeverity severity)
//    {
//      return ((int)facility * 8) + (int)severity;
//    }

//    #endregion // Public Static Members

//    #region Private Instances Fields

//    /// <summary>
//    /// The facility. The default facility is <see cref="SyslogFacility.User"/>.
//    /// </summary>
//    private SyslogFacility m_facility = SyslogFacility.User;

//    /// <summary>
//    /// The message identity
//    /// </summary>
//    private string m_identity;

//    /// <summary>
//    /// Marshaled handle to the identity string. We have to hold on to the
//    /// string as the <c>openlog</c> and <c>syslog</c> APIs just hold the
//    /// pointer to the ident and dereference it for each log message.
//    /// </summary>
//    private IntPtr m_handleToIdentity = IntPtr.Zero;

//    /// <summary>
//    /// Mapping from level object to syslog severity
//    /// </summary>
//    private LevelMapping m_levelMapping = new LevelMapping();

//    #endregion // Private Instances Fields

//    #region External Members
		
//    /// <summary>
//    /// Open connection to system logger.
//    /// </summary>
//    [DllImport("libc")]
//    private static extern void openlog(IntPtr ident, int option, SyslogFacility facility);

//    /// <summary>
//    /// Generate a log message.
//    /// </summary>
//    /// <remarks>
//    /// <para>
//    /// The libc syslog method takes a format string and a variable argument list similar
//    /// to the classic printf function. As this type of vararg list is not supported
//    /// by C# we need to specify the arguments explicitly. Here we have specified the
//    /// format string with a single message argument. The caller must set the format 
//    /// string to <c>"%s"</c>.
//    /// </para>
//    /// </remarks>
//    [DllImport("libc", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
//    private static extern void syslog(int priority, string format, string message);

//    /// <summary>
//    /// Close descriptor used to write to system logger.
//    /// </summary>
//    [DllImport("libc")]
//    private static extern void closelog();

//    #endregion // External Members

//    #region LevelSeverity LevelMapping Entry

//    /// <summary>
//    /// A class to act as a mapping between the level that a logging call is made at and
//    /// the syslog severity that is should be logged at.
//    /// </summary>
//    /// <remarks>
//    /// <para>
//    /// A class to act as a mapping between the level that a logging call is made at and
//    /// the syslog severity that is should be logged at.
//    /// </para>
//    /// </remarks>
//    public class LevelSeverity : LevelMappingEntry
//    {
//      private SyslogSeverity m_severity;

//      /// <summary>
//      /// The mapped syslog severity for the specified level
//      /// </summary>
//      /// <remarks>
//      /// <para>
//      /// Required property.
//      /// The mapped syslog severity for the specified level
//      /// </para>
//      /// </remarks>
//      public SyslogSeverity Severity
//      {
//        get { return m_severity; }
//        set { m_severity = value; }
//      }
//    }

//    #endregion // LevelSeverity LevelMapping Entry
//  }
//}

//#endif

		
		#endregion // Public Instance Properties

		/// <summary>
		/// Add a mapping of level to severity
		/// </summary>
		/// <param name="mapping">The mapping to add</param>
		/// <remarks>
		/// <para>
		/// Adds a <see cref="LevelSeverity"/> to this appender.
		/// </para>
		/// </remarks>
		public void AddMapping(LevelSeverity mapping)
		{
			m_levelMapping.Add(mapping);
		}

		#region IOptionHandler Implementation

		/// <summary>
		/// Initialize the appender based on the options set.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This is part of the <see cref="IOptionHandler"/> delayed object
		/// activation scheme. The <see cref="ActivateOptions"/> method must 
		/// be called on this object after the configuration properties have
		/// been set. Until <see cref="ActivateOptions"/> is called this
		/// object is in an undefined state and must not be used. 
		/// </para>
		/// <para>
		/// If any of the configuration properties are modified then 
		/// <see cref="ActivateOptions"/> must be called again.
		/// </para>
		/// </remarks>
		public override void ActivateOptions()
		{
			base.ActivateOptions();
			
			m_levelMapping.ActivateOptions();

			string identString = m_identity;
			if (identString == null)
			{
				// Set to app name by default
				identString = SystemInfo.ApplicationFriendlyName;
			}

			// create the native heap ansi string. Note this is a copy of our string
			// so we do not need to hold on to the string itself, holding on to the
			// handle will keep the heap ansi string alive.
			m_handleToIdentity = Marshal.StringToHGlobalAnsi(identString);

			// open syslog
			openlog(m_handleToIdentity, 1, m_facility);
		}

		#endregion // IOptionHandler Implementation

		#region AppenderSkeleton Implementation

		/// <summary>
		/// This method is called by the <see cref="AppenderSkeleton.DoAppend(LoggingEvent)"/> method.
		/// </summary>
		/// <param name="loggingEvent">The event to log.</param>
		/// <remarks>
		/// <para>
		/// Writes the event to a remote syslog daemon.
		/// </para>
		/// <para>
		/// The format of the output will depend on the appender's layout.
		/// </para>
		/// </remarks>
		protected override void Append(LoggingEvent loggingEvent) 
		{
			int priority = GeneratePriority(m_facility, GetSeverity(loggingEvent.Level));
			string message = RenderLoggingEvent(loggingEvent);

			// Call the local libc syslog method
			// The second argument is a printf style format string
			syslog(priority, "%s", message);
		}

		/// <summary>
		/// Close the syslog when the appender is closed
		/// </summary>
		/// <remarks>
		/// <para>
		/// Close the syslog when the appender is closed
		/// </para>
		/// </remarks>
		protected override void OnClose()
		{
			base.OnClose();

			try
			{
				// close syslog
				closelog();
			}
			catch(DllNotFoundException)
			{
				// Ignore dll not found at this point
			}
		
			if (m_handleToIdentity != IntPtr.Zero)
			{
				// free global ident
				Marshal.FreeHGlobal(m_handleToIdentity);
			}
		}

		#endregion // AppenderSkeleton Implementation

		#region Protected Members

		/// <summary>
		/// Translates a log4net level to a syslog severity.
		/// </summary>
		/// <param name="level">A log4net level.</param>
		/// <returns>A syslog severity.</returns>
		/// <remarks>
		/// <para>
		/// Translates a log4net level to a syslog severity.
		/// </para>
		/// </remarks>
		virtual protected SyslogSeverity GetSeverity(Level level)
		{
			LevelSeverity levelSeverity = m_levelMapping.Lookup(level) as LevelSeverity;
			if (levelSeverity != null)
			{
				return levelSeverity.Severity;
			}

			//
			// Fallback to sensible default values
			//

			if (level >= Level.Alert) 
			{
				return SyslogSeverity.Alert;
			} 
			else if (level >= Level.Critical) 
			{
				return SyslogSeverity.Critical;
			} 
			else if (level >= Level.Error) 
			{
				return SyslogSeverity.Error;
			} 
			else if (level >= Level.Warn) 
			{
				return SyslogSeverity.Warning;
			} 
			else if (level >= Level.Notice) 
			{
				return SyslogSeverity.Notice;
			} 
			else if (level >= Level.Info) 
			{
				return SyslogSeverity.Informational;
			} 
			// Default setting
			return SyslogSeverity.Debug;
		}

		#endregion // Protected Members

		#region Public Static Members

		/// <summary>
		/// Generate a syslog priority.
		/// </summary>
		/// <param name="facility">The syslog facility.</param>
		/// <param name="severity">The syslog severity.</param>
		/// <returns>A syslog priority.</returns>
		private static int GeneratePriority(SyslogFacility facility, SyslogSeverity severity)
		{
			return ((int)facility * 8) + (int)severity;
		}

log4net.Appender.LocalSyslogAppender : IAppender, IBulkAppender, IOptionHandler, IFlushable

Constructors :

public LocalSyslogAppender()

Methods :

public String get_Identity()
public Void set_Identity(String value = )
public SyslogFacility get_Facility()
public Void set_Facility(SyslogFacility value = )
public Void AddMapping(LevelSeverity mapping = )
public Void ActivateOptions()
public Level get_Threshold()
public Void set_Threshold(Level value = )
public IErrorHandler get_ErrorHandler()
public Void set_ErrorHandler(IErrorHandler value = )
public IFilter get_FilterHead()
public ILayout get_Layout()
public Void set_Layout(ILayout value = )
public String get_Name()
public Void set_Name(String value = )
public Void Close()
public Void DoAppend(LoggingEvent loggingEvent = )
public Void DoAppend(LoggingEvent[] loggingEvents = )
public Void AddFilter(IFilter filter = )
public Void ClearFilters()
public Boolean Flush(Int32 millisecondsTimeout = )
public Type GetType()
public String ToString()
public Boolean Equals(Object obj = )
public Int32 GetHashCode()

Other methods