N@poleone | 5 May 2009 11:42
Picon

Re: Different pattern layout based on Level

Hi,
my goal is to have different pattern layout based on the Level of the Logger. This cause I'd want to include line, method name etc. only if debug level is on.

Cause the appender section can include only one child element of type layout, I'm trying using two different appenders:

<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="Data\logs\logfile" />
    <appendToFile value="true" />
    <rollingStyle value="Composite" />
    <datepattern value="-yyyy-MM-dd.'log'" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="1MB" />
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date{ISO8601} | %-5level | [%thread] | %logger | %message %exception %newline" />
    </layout>
    <evaluator type="log4net.Core.LevelEvaluator">
      <threshold value="INFO"/>
    </evaluator>
  </appender>

  <appender name="RollingFileAppenderDebug" type="log4net.Appender.RollingFileAppender">
    <file value="Data\logs\logfile" />
    <appendToFile value="true" />
    <rollingStyle value="Composite" />
    <datepattern value="-yyyy-MM-dd.'log'" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="1MB" />
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date{ISO8601} | %-5level | [%thread] | %logger | %type | %method | %line | %message %exception %newline" />
    </layout>
  </appender>

  <root>
    <level value="INFO" />
    <appender-ref ref="RollingFileAppenderDebug" />
    <appender-ref ref="RollingFileAppender" />
  </root>

With this file I've some problem:

1) The two appenders doesn't log to the same file like I'd want... but I see two file named logfile-yyyy-MM-dd.log and logfile-yyyy-MM-dd.log-yyyy-MM-dd.log. The question is: How can I use tow RollingFileAppenders to log on the same file??

2) If I activate Debug then I'll have duplicate logs for every log statement from Info and above, right??

One solution could be to remove one appender at runtime based on the level specified: Info and above I'll remove the RollingFileAppenderDebug, Debug I'll remove the RollingFileAppender. How can I accomplish this??

Thanks to all.

N <at> poleone
nati159 | 11 May 2009 16:19
Picon

Number of rollbackfiles does not have the desired effect when the file name inc the process id


Hi,

I need to configure the settings so that the max number of files will be 10
and the max file size will be 100KB. 

Whenever I am not including the process id in my file name the machanism
works fine. The problem starts when I have many logs with different process
ids (closed by closing and opening the application). 

The "MaxSizeRollBackups" & "maximumFileSize" properties have an effect only
if the application stays open (i.e. for the same process id).

How can I make configure log4net to take into consideration all the log
files when rolling the file and not only the ones which belongs to the last
process id?

the relevant part from my config file is attached:

<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
		

        

        <maximumFileSize value="100KB" />

        
		<file type="log4net.Util.PatternString">
			<conversionPattern value="C:\log.ProcID_%processid.log" />
		</file>
		<threshold value="INFO"/>
		<layout type="log4net.Layout.PatternLayout">
			<conversionPattern value="%d [%t] %-5p [%c|%C.%M] - %m%n" />
		</layout>
</appender>

Thanks,
Natalie.
--

-- 
View this message in context: http://www.nabble.com/Number-of-rollbackfiles-does-not-have-the-desired-effect-when-the-file-name-inc-the-process-id-tp23484269p23484269.html
Sent from the Log4net - Users mailing list archive at Nabble.com.

ppden | 18 May 2009 23:13
Picon
Favicon

Remote Appender


Greetings,

I have been using log4net for a while and I think it rocks! It has allowed
me to focus on the business functionality and have provided a very reliable
and elegant platform for logging. So thanks to the people who maintain it. 

I have been trying all day to get the remote appender to work. I have looked
for examples but didn't find anything other than going into the source code
and checking out the unit tests. 

Here is my client class:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

using log4net.Core;
using IRemoteLoggingSink =
log4net.Appender.RemotingAppender.IRemoteLoggingSink;

namespace Miner.Responder.MultiSpeakInterfaces.Common
{
    public class RemoteLoggingSinkImpl : MarshalByRefObject,
IRemoteLoggingSink
	{
			public static readonly RemoteLoggingSinkImpl Instance = new
RemoteLoggingSinkImpl();
			public LoggingEvent[] Events = null;
            private TcpChannel m_remotingChannel;

			#region Public Instance Constructors
			private RemoteLoggingSinkImpl()
			{
			}

			#endregion Public Instance Constructors

            public void RegisterRemotingServerChannel()
		    {
			    if (m_remotingChannel == null)
			    {
				    m_remotingChannel = new TcpChannel(8085);

				    // Setup remoting server
				    try
				    {
					    ChannelServices.RegisterChannel(m_remotingChannel);
				    }
				    catch(Exception)
				    {
				    }

				    // Marshal the sink object
				    RemotingServices.Marshal(RemoteLoggingSinkImpl.Instance,
"LoggingSink", typeof(IRemoteLoggingSink));
			    }
    		}
			#region Implementation of IRemoteLoggingSink

			/// <summary>
			/// Logs the events to the repository.
			/// </summary>
			/// The events to log.
			/// <remarks>
			/// The events passed are logged to the <see cref="LoggerRepository"/>
			/// </remarks>
			public void LogEvents(LoggingEvent[] events)
			{
				Events = events;
			}

			#endregion Implementation of IRemoteLoggingSink

			#region Override implementation of MarshalByRefObject

			/// <summary>
			/// Obtains a lifetime service object to control the lifetime 
			/// policy for this instance.
			/// </summary>
			/// <returns>
			/// <c>null</c> to indicate that this instance should live
			/// forever.
			/// </returns>
			public override object InitializeLifetimeService()
			{
				return null;
			}

			#endregion Override implementation of MarshalByRefObject
		}
}

Pretty simple, correct?

My server is also very simple. Here is the configuration:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <configSections>
    <section name="log4net" type="System.Configuration.IgnoreSectionHandler"
/>
  </configSections>
  <log4net>
    <root>
      <level value="ERROR" />
      <appender-ref ref="EventLogAppender" />
      <appender-ref ref="FileAppender" />
      <appender-ref ref="RemotingAppender"/>
      <level value="INFO"/>
      <appender-ref ref="FileAppender" />
      <appender-ref ref="RemotingAppender"/>
    </root>

    <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern
           value="%date [%thread] %-5level %logger [%property{NDC}] -
%message%newline" />
      </layout>
    </appender>

    <appender name="ConsoleAppender"
type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern
           value="%date [%thread] %-5level %logger [%property{NDC}] -
%message%newline" />
      </layout>
    </appender>

    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="c:\\Log\\log-file.txt" />
      <appendToFile value="true" />
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern
           value="%date [%thread] %-5level %logger [%property{NDC}] -
%message%newline" />
      </layout>
    </appender>

    <appender name="EventLogAppender"
type="log4net.Appender.EventLogAppender" >
      <applicationName value="Test Service" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
      </layout>
    </appender>

    <appender name="RemotingAppender"
type="log4net.Appender.RemotingAppender" >
      <sink value="tcp://localhost:8085/LoggingSink" />
      <lossy value="false" />
      <bufferSize value="95" />
      <onlyFixPartialEventData value="true" />
    </appender>

  </log4net>

</configuration>

and my server code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private static readonly log4net.ILog _log =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            while (true)
            {
                _log.Info(DateTime.Now.ToLongTimeString());
                Thread.Sleep(1000 * 10);
            }
        }
    }
}

I can see the remoting listener start but a connection is never made. The
server is generating the messages, I can see then on the event log. Any
ideas?

Cheers,

PP

--

-- 
View this message in context: http://www.nabble.com/Remote-Appender-tp23605546p23605546.html
Sent from the Log4net - Users mailing list archive at Nabble.com.

Loren Keagle | 19 May 2009 01:21

Re: Remote Appender

With a buffer of 95, you won't see anything on the remote appender until 
95 log events have been queued.  I ended up subclassing the appender to 
add a timer to flush automatically every N seconds.  Try setting the 
buffer length down to 1 or disable it entirely. 

~Loren

ppden wrote:
> Greetings,
>
> I have been using log4net for a while and I think it rocks! It has allowed
> me to focus on the business functionality and have provided a very reliable
> and elegant platform for logging. So thanks to the people who maintain it. 
>
> I have been trying all day to get the remote appender to work. I have looked
> for examples but didn't find anything other than going into the source code
> and checking out the unit tests. 
>
> Here is my client class:
>
> using System;
> using System.Collections.Generic;
> using System.Text;
> using System.Runtime.Remoting;
> using System.Runtime.Remoting.Channels;
> using System.Runtime.Remoting.Channels.Tcp;
>
> using log4net.Core;
> using IRemoteLoggingSink =
> log4net.Appender.RemotingAppender.IRemoteLoggingSink;
>
> namespace Miner.Responder.MultiSpeakInterfaces.Common
> {
>     public class RemoteLoggingSinkImpl : MarshalByRefObject,
> IRemoteLoggingSink
> 	{
> 			public static readonly RemoteLoggingSinkImpl Instance = new
> RemoteLoggingSinkImpl();
> 			public LoggingEvent[] Events = null;
>             private TcpChannel m_remotingChannel;
>
> 			#region Public Instance Constructors
> 			private RemoteLoggingSinkImpl()
> 			{
> 			}
>
> 			#endregion Public Instance Constructors
>
>             public void RegisterRemotingServerChannel()
> 		    {
> 			    if (m_remotingChannel == null)
> 			    {
> 				    m_remotingChannel = new TcpChannel(8085);
>
> 				    // Setup remoting server
> 				    try
> 				    {
> 					    ChannelServices.RegisterChannel(m_remotingChannel);
> 				    }
> 				    catch(Exception)
> 				    {
> 				    }
>
> 				    // Marshal the sink object
> 				    RemotingServices.Marshal(RemoteLoggingSinkImpl.Instance,
> "LoggingSink", typeof(IRemoteLoggingSink));
> 			    }
>     		}
> 			#region Implementation of IRemoteLoggingSink
>
> 			/// <summary>
> 			/// Logs the events to the repository.
> 			/// </summary>
> 			/// The events to log.
> 			/// <remarks>
> 			/// The events passed are logged to the <see cref="LoggerRepository"/>
> 			/// </remarks>
> 			public void LogEvents(LoggingEvent[] events)
> 			{
> 				Events = events;
> 			}
>
> 			#endregion Implementation of IRemoteLoggingSink
>
> 			#region Override implementation of MarshalByRefObject
>
> 			/// <summary>
> 			/// Obtains a lifetime service object to control the lifetime 
> 			/// policy for this instance.
> 			/// </summary>
> 			/// <returns>
> 			/// <c>null</c> to indicate that this instance should live
> 			/// forever.
> 			/// </returns>
> 			public override object InitializeLifetimeService()
> 			{
> 				return null;
> 			}
>
> 			#endregion Override implementation of MarshalByRefObject
> 		}
> }
>
>
> Pretty simple, correct?
>
> My server is also very simple. Here is the configuration:
>
> <?xml version="1.0" encoding="utf-8" ?>
> <configuration>
>
>   <configSections>
>     <section name="log4net" type="System.Configuration.IgnoreSectionHandler"
> />
>   </configSections>
>   <log4net>
>     <root>
>       <level value="ERROR" />
>       <appender-ref ref="EventLogAppender" />
>       <appender-ref ref="FileAppender" />
>       <appender-ref ref="RemotingAppender"/>
>       <level value="INFO"/>
>       <appender-ref ref="FileAppender" />
>       <appender-ref ref="RemotingAppender"/>
>     </root>
>
>     <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
>       <layout type="log4net.Layout.PatternLayout">
>         <conversionPattern
>            value="%date [%thread] %-5level %logger [%property{NDC}] -
> %message%newline" />
>       </layout>
>     </appender>
>
>     <appender name="ConsoleAppender"
> type="log4net.Appender.ConsoleAppender">
>       <layout type="log4net.Layout.PatternLayout">
>         <conversionPattern
>            value="%date [%thread] %-5level %logger [%property{NDC}] -
> %message%newline" />
>       </layout>
>     </appender>
>
>     <appender name="FileAppender" type="log4net.Appender.FileAppender">
>       <file value="c:\\Log\\log-file.txt" />
>       <appendToFile value="true" />
>       <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
>       <layout type="log4net.Layout.PatternLayout">
>         <conversionPattern
>            value="%date [%thread] %-5level %logger [%property{NDC}] -
> %message%newline" />
>       </layout>
>     </appender>
>
>     <appender name="EventLogAppender"
> type="log4net.Appender.EventLogAppender" >
>       <applicationName value="Test Service" />
>       <layout type="log4net.Layout.PatternLayout">
>         <conversionPattern value="%date [%thread] %-5level %logger
> [%property{NDC}] - %message%newline" />
>       </layout>
>     </appender>
>
>     <appender name="RemotingAppender"
> type="log4net.Appender.RemotingAppender" >
>       <sink value="tcp://localhost:8085/LoggingSink" />
>       <lossy value="false" />
>       <bufferSize value="95" />
>       <onlyFixPartialEventData value="true" />
>     </appender>
>
>
>
>   </log4net>
>
> </configuration>
>
> and my server code:
>
> using System;
> using System.Collections.Generic;
> using System.ComponentModel;
> using System.Data;
> using System.Drawing;
> using System.Linq;
> using System.Text;
> using System.Threading;
> using System.Windows.Forms;
>
> namespace WindowsFormsApplication1
> {
>     public partial class Form1 : Form
>     {
>         private static readonly log4net.ILog _log =
> log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
>         public Form1()
>         {
>             InitializeComponent();
>         }
>
>         private void button1_Click(object sender, EventArgs e)
>         {
>             while (true)
>             {
>                 _log.Info(DateTime.Now.ToLongTimeString());
>                 Thread.Sleep(1000 * 10);
>             }
>         }
>     }
> }
>
>
> I can see the remoting listener start but a connection is never made. The
> server is generating the messages, I can see then on the event log. Any
> ideas?
>
> Cheers,
>
> PP
>
>   
> ------------------------------------------------------------------------
>
>
> No virus found in this incoming message.
> Checked by AVG - www.avg.com 
> Version: 8.5.339 / Virus Database: 270.12.33/2120 - Release Date: 05/18/09 06:28:00
>
>   

ppden | 19 May 2009 01:59
Picon
Favicon

Re: Remote Appender


Thanks Loren. However, it still doesn't work. I looked into the source for
the remote appender and at no point I see the channel registration. What is
version of log4net ar you using? When you sub-classes the appender, did you
handle the .net remoting connection (channel services and remoting
configuration) yourself?

Loren Keagle wrote:
> 
> With a buffer of 95, you won't see anything on the remote appender until 
> 95 log events have been queued.  I ended up subclassing the appender to 
> add a timer to flush automatically every N seconds.  Try setting the 
> buffer length down to 1 or disable it entirely. 
> 
> ~Loren
> 
> ppden wrote:
>> Greetings,
>>
>> I have been using log4net for a while and I think it rocks! It has
>> allowed
>> me to focus on the business functionality and have provided a very
>> reliable
>> and elegant platform for logging. So thanks to the people who maintain
>> it. 
>>
>> I have been trying all day to get the remote appender to work. I have
>> looked
>> for examples but didn't find anything other than going into the source
>> code
>> and checking out the unit tests. 
>>
>> Here is my client class:
>>
>> using System;
>> using System.Collections.Generic;
>> using System.Text;
>> using System.Runtime.Remoting;
>> using System.Runtime.Remoting.Channels;
>> using System.Runtime.Remoting.Channels.Tcp;
>>
>> using log4net.Core;
>> using IRemoteLoggingSink =
>> log4net.Appender.RemotingAppender.IRemoteLoggingSink;
>>
>> namespace Miner.Responder.MultiSpeakInterfaces.Common
>> {
>>     public class RemoteLoggingSinkImpl : MarshalByRefObject,
>> IRemoteLoggingSink
>> 	{
>> 			public static readonly RemoteLoggingSinkImpl Instance = new
>> RemoteLoggingSinkImpl();
>> 			public LoggingEvent[] Events = null;
>>             private TcpChannel m_remotingChannel;
>>
>> 			#region Public Instance Constructors
>> 			private RemoteLoggingSinkImpl()
>> 			{
>> 			}
>>
>> 			#endregion Public Instance Constructors
>>
>>             public void RegisterRemotingServerChannel()
>> 		    {
>> 			    if (m_remotingChannel == null)
>> 			    {
>> 				    m_remotingChannel = new TcpChannel(8085);
>>
>> 				    // Setup remoting server
>> 				    try
>> 				    {
>> 					    ChannelServices.RegisterChannel(m_remotingChannel);
>> 				    }
>> 				    catch(Exception)
>> 				    {
>> 				    }
>>
>> 				    // Marshal the sink object
>> 				    RemotingServices.Marshal(RemoteLoggingSinkImpl.Instance,
>> "LoggingSink", typeof(IRemoteLoggingSink));
>> 			    }
>>     		}
>> 			#region Implementation of IRemoteLoggingSink
>>
>> 			/// <summary>
>> 			/// Logs the events to the repository.
>> 			/// </summary>
>> 			/// The events to log.
>> 			/// <remarks>
>> 			/// The events passed are logged to the <see cref="LoggerRepository"/>
>> 			/// </remarks>
>> 			public void LogEvents(LoggingEvent[] events)
>> 			{
>> 				Events = events;
>> 			}
>>
>> 			#endregion Implementation of IRemoteLoggingSink
>>
>> 			#region Override implementation of MarshalByRefObject
>>
>> 			/// <summary>
>> 			/// Obtains a lifetime service object to control the lifetime 
>> 			/// policy for this instance.
>> 			/// </summary>
>> 			/// <returns>
>> 			/// <c>null</c> to indicate that this instance should live
>> 			/// forever.
>> 			/// </returns>
>> 			public override object InitializeLifetimeService()
>> 			{
>> 				return null;
>> 			}
>>
>> 			#endregion Override implementation of MarshalByRefObject
>> 		}
>> }
>>
>>
>> Pretty simple, correct?
>>
>> My server is also very simple. Here is the configuration:
>>
>> <?xml version="1.0" encoding="utf-8" ?>
>> <configuration>
>>
>>   <configSections>
>>     <section name="log4net"
>> type="System.Configuration.IgnoreSectionHandler"
>> />
>>   </configSections>
>>   <log4net>
>>     <root>
>>       <level value="ERROR" />
>>       <appender-ref ref="EventLogAppender" />
>>       <appender-ref ref="FileAppender" />
>>       <appender-ref ref="RemotingAppender"/>
>>       <level value="INFO"/>
>>       <appender-ref ref="FileAppender" />
>>       <appender-ref ref="RemotingAppender"/>
>>     </root>
>>
>>     <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
>>       <layout type="log4net.Layout.PatternLayout">
>>         <conversionPattern
>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>> %message%newline" />
>>       </layout>
>>     </appender>
>>
>>     <appender name="ConsoleAppender"
>> type="log4net.Appender.ConsoleAppender">
>>       <layout type="log4net.Layout.PatternLayout">
>>         <conversionPattern
>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>> %message%newline" />
>>       </layout>
>>     </appender>
>>
>>     <appender name="FileAppender" type="log4net.Appender.FileAppender">
>>       <file value="c:\\Log\\log-file.txt" />
>>       <appendToFile value="true" />
>>       <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
>>       <layout type="log4net.Layout.PatternLayout">
>>         <conversionPattern
>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>> %message%newline" />
>>       </layout>
>>     </appender>
>>
>>     <appender name="EventLogAppender"
>> type="log4net.Appender.EventLogAppender" >
>>       <applicationName value="Test Service" />
>>       <layout type="log4net.Layout.PatternLayout">
>>         <conversionPattern value="%date [%thread] %-5level %logger
>> [%property{NDC}] - %message%newline" />
>>       </layout>
>>     </appender>
>>
>>     <appender name="RemotingAppender"
>> type="log4net.Appender.RemotingAppender" >
>>       <sink value="tcp://localhost:8085/LoggingSink" />
>>       <lossy value="false" />
>>       <bufferSize value="95" />
>>       <onlyFixPartialEventData value="true" />
>>     </appender>
>>
>>
>>
>>   </log4net>
>>
>> </configuration>
>>
>> and my server code:
>>
>> using System;
>> using System.Collections.Generic;
>> using System.ComponentModel;
>> using System.Data;
>> using System.Drawing;
>> using System.Linq;
>> using System.Text;
>> using System.Threading;
>> using System.Windows.Forms;
>>
>> namespace WindowsFormsApplication1
>> {
>>     public partial class Form1 : Form
>>     {
>>         private static readonly log4net.ILog _log =
>> log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
>>         public Form1()
>>         {
>>             InitializeComponent();
>>         }
>>
>>         private void button1_Click(object sender, EventArgs e)
>>         {
>>             while (true)
>>             {
>>                 _log.Info(DateTime.Now.ToLongTimeString());
>>                 Thread.Sleep(1000 * 10);
>>             }
>>         }
>>     }
>> }
>>
>>
>> I can see the remoting listener start but a connection is never made. The
>> server is generating the messages, I can see then on the event log. Any
>> ideas?
>>
>> Cheers,
>>
>> PP
>>
>>   
>> ------------------------------------------------------------------------
>>
>>
>> No virus found in this incoming message.
>> Checked by AVG - www.avg.com 
>> Version: 8.5.339 / Virus Database: 270.12.33/2120 - Release Date:
>> 05/18/09 06:28:00
>>
>>   
> 
> 
> 

--

-- 
View this message in context: http://www.nabble.com/Remote-Appender-tp23605546p23607353.html
Sent from the Log4net - Users mailing list archive at Nabble.com.

Loren Keagle | 19 May 2009 02:17

Re: Remote Appender

I did not alter the connection functionality at all.  I simply added a 
timer: to the log4net 1.2.10 RemotingAppender as follows:

public class TimedRemotingAppender : RemotingAppender
    {
        public TimedRemotingAppender()
        {
            FlushPeriod = 10; // seconds
            timer = new Timer(FlushBuffer);
        }

        /// <summary>
        /// The period, in seconds, at which the buffer is sent 
regardless of being full
        /// </summary>
        public int FlushPeriod { get; set; }

        private readonly Timer timer;
        private void FlushBuffer(object state) { Flush(); }

        protected override void Append(LoggingEvent loggingEvent)
        {
            base.Append(loggingEvent);
            timer.Change(FlushPeriod * 1000, Timeout.Infinite);
        }
    }

Which is configured the same as the RemotingAppender:

    <appender name="RemotingAppender" 
type="APS.Gate.TimedRemotingAppender" >
      <sink value="tcp://localhost:9250/LoggingSink" />
      <bufferSize value="100" />
      <flushPeriod>20</flushPeriod>
    </appender>

My server implementation is also trivially simple:

public class RemotingLogger : MarshalByRefObject, 
RemotingAppender.IRemoteLoggingSink
    {
        private static readonly ILog logger = 
LogManager.GetLogger(typeof(RemotingLogger));

        public void LogEvents(LoggingEvent[] events)
        {
            if (events == null) return;
            lock (this)
            {
                foreach (LoggingEvent le in events)
                {
                    logger.Logger.Log(le);
                }
            }
        }
    }

All that is required for me is to add the following code to your remote 
event sink:

TcpServerChannel channel = new 
TcpServerChannel(Settings.Default.RemotingPort);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingLogger), 
"LoggingSink", WellKnownObjectMode.Singleton);

This works fine for me.  Perhaps you have a firewall issue?  My example 
is for source and sink on the same machine.  If the sink is on a 
different machine, you'll need to open up your firewall for the port you 
decide to use.

~Loren

ppden wrote:
> Thanks Loren. However, it still doesn't work. I looked into the source for
> the remote appender and at no point I see the channel registration. What is
> version of log4net ar you using? When you sub-classes the appender, did you
> handle the .net remoting connection (channel services and remoting
> configuration) yourself?
>
>
>
> Loren Keagle wrote:
>   
>> With a buffer of 95, you won't see anything on the remote appender until 
>> 95 log events have been queued.  I ended up subclassing the appender to 
>> add a timer to flush automatically every N seconds.  Try setting the 
>> buffer length down to 1 or disable it entirely. 
>>
>> ~Loren
>>
>> ppden wrote:
>>     
>>> Greetings,
>>>
>>> I have been using log4net for a while and I think it rocks! It has
>>> allowed
>>> me to focus on the business functionality and have provided a very
>>> reliable
>>> and elegant platform for logging. So thanks to the people who maintain
>>> it. 
>>>
>>> I have been trying all day to get the remote appender to work. I have
>>> looked
>>> for examples but didn't find anything other than going into the source
>>> code
>>> and checking out the unit tests. 
>>>
>>> Here is my client class:
>>>
>>> using System;
>>> using System.Collections.Generic;
>>> using System.Text;
>>> using System.Runtime.Remoting;
>>> using System.Runtime.Remoting.Channels;
>>> using System.Runtime.Remoting.Channels.Tcp;
>>>
>>> using log4net.Core;
>>> using IRemoteLoggingSink =
>>> log4net.Appender.RemotingAppender.IRemoteLoggingSink;
>>>
>>> namespace Miner.Responder.MultiSpeakInterfaces.Common
>>> {
>>>     public class RemoteLoggingSinkImpl : MarshalByRefObject,
>>> IRemoteLoggingSink
>>> 	{
>>> 			public static readonly RemoteLoggingSinkImpl Instance = new
>>> RemoteLoggingSinkImpl();
>>> 			public LoggingEvent[] Events = null;
>>>             private TcpChannel m_remotingChannel;
>>>
>>> 			#region Public Instance Constructors
>>> 			private RemoteLoggingSinkImpl()
>>> 			{
>>> 			}
>>>
>>> 			#endregion Public Instance Constructors
>>>
>>>             public void RegisterRemotingServerChannel()
>>> 		    {
>>> 			    if (m_remotingChannel == null)
>>> 			    {
>>> 				    m_remotingChannel = new TcpChannel(8085);
>>>
>>> 				    // Setup remoting server
>>> 				    try
>>> 				    {
>>> 					    ChannelServices.RegisterChannel(m_remotingChannel);
>>> 				    }
>>> 				    catch(Exception)
>>> 				    {
>>> 				    }
>>>
>>> 				    // Marshal the sink object
>>> 				    RemotingServices.Marshal(RemoteLoggingSinkImpl.Instance,
>>> "LoggingSink", typeof(IRemoteLoggingSink));
>>> 			    }
>>>     		}
>>> 			#region Implementation of IRemoteLoggingSink
>>>
>>> 			/// <summary>
>>> 			/// Logs the events to the repository.
>>> 			/// </summary>
>>> 			/// The events to log.
>>> 			/// <remarks>
>>> 			/// The events passed are logged to the <see cref="LoggerRepository"/>
>>> 			/// </remarks>
>>> 			public void LogEvents(LoggingEvent[] events)
>>> 			{
>>> 				Events = events;
>>> 			}
>>>
>>> 			#endregion Implementation of IRemoteLoggingSink
>>>
>>> 			#region Override implementation of MarshalByRefObject
>>>
>>> 			/// <summary>
>>> 			/// Obtains a lifetime service object to control the lifetime 
>>> 			/// policy for this instance.
>>> 			/// </summary>
>>> 			/// <returns>
>>> 			/// <c>null</c> to indicate that this instance should live
>>> 			/// forever.
>>> 			/// </returns>
>>> 			public override object InitializeLifetimeService()
>>> 			{
>>> 				return null;
>>> 			}
>>>
>>> 			#endregion Override implementation of MarshalByRefObject
>>> 		}
>>> }
>>>
>>>
>>> Pretty simple, correct?
>>>
>>> My server is also very simple. Here is the configuration:
>>>
>>> <?xml version="1.0" encoding="utf-8" ?>
>>> <configuration>
>>>
>>>   <configSections>
>>>     <section name="log4net"
>>> type="System.Configuration.IgnoreSectionHandler"
>>> />
>>>   </configSections>
>>>   <log4net>
>>>     <root>
>>>       <level value="ERROR" />
>>>       <appender-ref ref="EventLogAppender" />
>>>       <appender-ref ref="FileAppender" />
>>>       <appender-ref ref="RemotingAppender"/>
>>>       <level value="INFO"/>
>>>       <appender-ref ref="FileAppender" />
>>>       <appender-ref ref="RemotingAppender"/>
>>>     </root>
>>>
>>>     <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
>>>       <layout type="log4net.Layout.PatternLayout">
>>>         <conversionPattern
>>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>>> %message%newline" />
>>>       </layout>
>>>     </appender>
>>>
>>>     <appender name="ConsoleAppender"
>>> type="log4net.Appender.ConsoleAppender">
>>>       <layout type="log4net.Layout.PatternLayout">
>>>         <conversionPattern
>>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>>> %message%newline" />
>>>       </layout>
>>>     </appender>
>>>
>>>     <appender name="FileAppender" type="log4net.Appender.FileAppender">
>>>       <file value="c:\\Log\\log-file.txt" />
>>>       <appendToFile value="true" />
>>>       <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
>>>       <layout type="log4net.Layout.PatternLayout">
>>>         <conversionPattern
>>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>>> %message%newline" />
>>>       </layout>
>>>     </appender>
>>>
>>>     <appender name="EventLogAppender"
>>> type="log4net.Appender.EventLogAppender" >
>>>       <applicationName value="Test Service" />
>>>       <layout type="log4net.Layout.PatternLayout">
>>>         <conversionPattern value="%date [%thread] %-5level %logger
>>> [%property{NDC}] - %message%newline" />
>>>       </layout>
>>>     </appender>
>>>
>>>     <appender name="RemotingAppender"
>>> type="log4net.Appender.RemotingAppender" >
>>>       <sink value="tcp://localhost:8085/LoggingSink" />
>>>       <lossy value="false" />
>>>       <bufferSize value="95" />
>>>       <onlyFixPartialEventData value="true" />
>>>     </appender>
>>>
>>>
>>>
>>>   </log4net>
>>>
>>> </configuration>
>>>
>>> and my server code:
>>>
>>> using System;
>>> using System.Collections.Generic;
>>> using System.ComponentModel;
>>> using System.Data;
>>> using System.Drawing;
>>> using System.Linq;
>>> using System.Text;
>>> using System.Threading;
>>> using System.Windows.Forms;
>>>
>>> namespace WindowsFormsApplication1
>>> {
>>>     public partial class Form1 : Form
>>>     {
>>>         private static readonly log4net.ILog _log =
>>> log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
>>>         public Form1()
>>>         {
>>>             InitializeComponent();
>>>         }
>>>
>>>         private void button1_Click(object sender, EventArgs e)
>>>         {
>>>             while (true)
>>>             {
>>>                 _log.Info(DateTime.Now.ToLongTimeString());
>>>                 Thread.Sleep(1000 * 10);
>>>             }
>>>         }
>>>     }
>>> }
>>>
>>>
>>> I can see the remoting listener start but a connection is never made. The
>>> server is generating the messages, I can see then on the event log. Any
>>> ideas?
>>>
>>> Cheers,
>>>
>>> PP
>>>
>>>   
>>> ------------------------------------------------------------------------
>>>
>>>
>>> No virus found in this incoming message.
>>> Checked by AVG - www.avg.com 
>>> Version: 8.5.339 / Virus Database: 270.12.33/2120 - Release Date:
>>> 05/18/09 06:28:00
>>>
>>>   
>>>       
>>
>>     
>
>   
> ------------------------------------------------------------------------
>
>
> No virus found in this incoming message.
> Checked by AVG - www.avg.com 
> Version: 8.5.339 / Virus Database: 270.12.33/2120 - Release Date: 05/18/09 06:28:00
>
>   

ppden | 19 May 2009 02:57
Picon
Favicon

Re: Remote Appender


Thanks again for your help. But now I am at a bit of a loss. If the sink
class on the server side or on the client? I assume it was on the client
side, but as per you code it appears to be on the server side.

Also, I notice that you are not using the same pattern I use to log events.
I just use the basic log.Info(...) and the reason I though it would be a
good idea to use the remote appender is because I don't have to change the
code (over 2 milion lines of code with lots of log.info) and handle
everything by adding the new appender to the configuration file. Am I
completely wrong? 

Loren Keagle wrote:
> 
> I did not alter the connection functionality at all.  I simply added a 
> timer: to the log4net 1.2.10 RemotingAppender as follows:
> 
> 
> public class TimedRemotingAppender : RemotingAppender
>     {
>         public TimedRemotingAppender()
>         {
>             FlushPeriod = 10; // seconds
>             timer = new Timer(FlushBuffer);
>         }
> 
>         /// <summary>
>         /// The period, in seconds, at which the buffer is sent 
> regardless of being full
>         /// </summary>
>         public int FlushPeriod { get; set; }
> 
>         private readonly Timer timer;
>         private void FlushBuffer(object state) { Flush(); }
> 
>         protected override void Append(LoggingEvent loggingEvent)
>         {
>             base.Append(loggingEvent);
>             timer.Change(FlushPeriod * 1000, Timeout.Infinite);
>         }
>     }
> 
> Which is configured the same as the RemotingAppender:
> 
>     <appender name="RemotingAppender" 
> type="APS.Gate.TimedRemotingAppender" >
>       <sink value="tcp://localhost:9250/LoggingSink" />
>       <bufferSize value="100" />
>       <flushPeriod>20</flushPeriod>
>     </appender>
> 
> 
> My server implementation is also trivially simple:
> 
> public class RemotingLogger : MarshalByRefObject, 
> RemotingAppender.IRemoteLoggingSink
>     {
>         private static readonly ILog logger = 
> LogManager.GetLogger(typeof(RemotingLogger));
> 
>         public void LogEvents(LoggingEvent[] events)
>         {
>             if (events == null) return;
>             lock (this)
>             {
>                 foreach (LoggingEvent le in events)
>                 {
>                     logger.Logger.Log(le);
>                 }
>             }
>         }
>     }
> 
> All that is required for me is to add the following code to your remote 
> event sink:
> 
> TcpServerChannel channel = new 
> TcpServerChannel(Settings.Default.RemotingPort);
> ChannelServices.RegisterChannel(channel, false);
> RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingLogger), 
> "LoggingSink", WellKnownObjectMode.Singleton);
> 
> 
> This works fine for me.  Perhaps you have a firewall issue?  My example 
> is for source and sink on the same machine.  If the sink is on a 
> different machine, you'll need to open up your firewall for the port you 
> decide to use.
> 
> ~Loren
> 
> 
> 
> ppden wrote:
>> Thanks Loren. However, it still doesn't work. I looked into the source
>> for
>> the remote appender and at no point I see the channel registration. What
>> is
>> version of log4net ar you using? When you sub-classes the appender, did
>> you
>> handle the .net remoting connection (channel services and remoting
>> configuration) yourself?
>>
>>
>>
>> Loren Keagle wrote:
>>   
>>> With a buffer of 95, you won't see anything on the remote appender until 
>>> 95 log events have been queued.  I ended up subclassing the appender to 
>>> add a timer to flush automatically every N seconds.  Try setting the 
>>> buffer length down to 1 or disable it entirely. 
>>>
>>> ~Loren
>>>
>>> ppden wrote:
>>>     
>>>> Greetings,
>>>>
>>>> I have been using log4net for a while and I think it rocks! It has
>>>> allowed
>>>> me to focus on the business functionality and have provided a very
>>>> reliable
>>>> and elegant platform for logging. So thanks to the people who maintain
>>>> it. 
>>>>
>>>> I have been trying all day to get the remote appender to work. I have
>>>> looked
>>>> for examples but didn't find anything other than going into the source
>>>> code
>>>> and checking out the unit tests. 
>>>>
>>>> Here is my client class:
>>>>
>>>> using System;
>>>> using System.Collections.Generic;
>>>> using System.Text;
>>>> using System.Runtime.Remoting;
>>>> using System.Runtime.Remoting.Channels;
>>>> using System.Runtime.Remoting.Channels.Tcp;
>>>>
>>>> using log4net.Core;
>>>> using IRemoteLoggingSink =
>>>> log4net.Appender.RemotingAppender.IRemoteLoggingSink;
>>>>
>>>> namespace Miner.Responder.MultiSpeakInterfaces.Common
>>>> {
>>>>     public class RemoteLoggingSinkImpl : MarshalByRefObject,
>>>> IRemoteLoggingSink
>>>> 	{
>>>> 			public static readonly RemoteLoggingSinkImpl Instance = new
>>>> RemoteLoggingSinkImpl();
>>>> 			public LoggingEvent[] Events = null;
>>>>             private TcpChannel m_remotingChannel;
>>>>
>>>> 			#region Public Instance Constructors
>>>> 			private RemoteLoggingSinkImpl()
>>>> 			{
>>>> 			}
>>>>
>>>> 			#endregion Public Instance Constructors
>>>>
>>>>             public void RegisterRemotingServerChannel()
>>>> 		    {
>>>> 			    if (m_remotingChannel == null)
>>>> 			    {
>>>> 				    m_remotingChannel = new TcpChannel(8085);
>>>>
>>>> 				    // Setup remoting server
>>>> 				    try
>>>> 				    {
>>>> 					    ChannelServices.RegisterChannel(m_remotingChannel);
>>>> 				    }
>>>> 				    catch(Exception)
>>>> 				    {
>>>> 				    }
>>>>
>>>> 				    // Marshal the sink object
>>>> 				    RemotingServices.Marshal(RemoteLoggingSinkImpl.Instance,
>>>> "LoggingSink", typeof(IRemoteLoggingSink));
>>>> 			    }
>>>>     		}
>>>> 			#region Implementation of IRemoteLoggingSink
>>>>
>>>> 			/// <summary>
>>>> 			/// Logs the events to the repository.
>>>> 			/// </summary>
>>>> 			/// The events to log.
>>>> 			/// <remarks>
>>>> 			/// The events passed are logged to the <see
>>>> cref="LoggerRepository"/>
>>>> 			/// </remarks>
>>>> 			public void LogEvents(LoggingEvent[] events)
>>>> 			{
>>>> 				Events = events;
>>>> 			}
>>>>
>>>> 			#endregion Implementation of IRemoteLoggingSink
>>>>
>>>> 			#region Override implementation of MarshalByRefObject
>>>>
>>>> 			/// <summary>
>>>> 			/// Obtains a lifetime service object to control the lifetime 
>>>> 			/// policy for this instance.
>>>> 			/// </summary>
>>>> 			/// <returns>
>>>> 			/// <c>null</c> to indicate that this instance should live
>>>> 			/// forever.
>>>> 			/// </returns>
>>>> 			public override object InitializeLifetimeService()
>>>> 			{
>>>> 				return null;
>>>> 			}
>>>>
>>>> 			#endregion Override implementation of MarshalByRefObject
>>>> 		}
>>>> }
>>>>
>>>>
>>>> Pretty simple, correct?
>>>>
>>>> My server is also very simple. Here is the configuration:
>>>>
>>>> <?xml version="1.0" encoding="utf-8" ?>
>>>> <configuration>
>>>>
>>>>   <configSections>
>>>>     <section name="log4net"
>>>> type="System.Configuration.IgnoreSectionHandler"
>>>> />
>>>>   </configSections>
>>>>   <log4net>
>>>>     <root>
>>>>       <level value="ERROR" />
>>>>       <appender-ref ref="EventLogAppender" />
>>>>       <appender-ref ref="FileAppender" />
>>>>       <appender-ref ref="RemotingAppender"/>
>>>>       <level value="INFO"/>
>>>>       <appender-ref ref="FileAppender" />
>>>>       <appender-ref ref="RemotingAppender"/>
>>>>     </root>
>>>>
>>>>     <appender name="TraceAppender"
>>>> type="log4net.Appender.TraceAppender">
>>>>       <layout type="log4net.Layout.PatternLayout">
>>>>         <conversionPattern
>>>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>>>> %message%newline" />
>>>>       </layout>
>>>>     </appender>
>>>>
>>>>     <appender name="ConsoleAppender"
>>>> type="log4net.Appender.ConsoleAppender">
>>>>       <layout type="log4net.Layout.PatternLayout">
>>>>         <conversionPattern
>>>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>>>> %message%newline" />
>>>>       </layout>
>>>>     </appender>
>>>>
>>>>     <appender name="FileAppender" type="log4net.Appender.FileAppender">
>>>>       <file value="c:\\Log\\log-file.txt" />
>>>>       <appendToFile value="true" />
>>>>       <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
>>>>       <layout type="log4net.Layout.PatternLayout">
>>>>         <conversionPattern
>>>>            value="%date [%thread] %-5level %logger [%property{NDC}] -
>>>> %message%newline" />
>>>>       </layout>
>>>>     </appender>
>>>>
>>>>     <appender name="EventLogAppender"
>>>> type="log4net.Appender.EventLogAppender" >
>>>>       <applicationName value="Test Service" />
>>>>       <layout type="log4net.Layout.PatternLayout">
>>>>         <conversionPattern value="%date [%thread] %-5level %logger
>>>> [%property{NDC}] - %message%newline" />
>>>>       </layout>
>>>>     </appender>
>>>>
>>>>     <appender name="RemotingAppender"
>>>> type="log4net.Appender.RemotingAppender" >
>>>>       <sink value="tcp://localhost:8085/LoggingSink" />
>>>>       <lossy value="false" />
>>>>       <bufferSize value="95" />
>>>>       <onlyFixPartialEventData value="true" />
>>>>     </appender>
>>>>
>>>>
>>>>
>>>>   </log4net>
>>>>
>>>> </configuration>
>>>>
>>>> and my server code:
>>>>
>>>> using System;
>>>> using System.Collections.Generic;
>>>> using System.ComponentModel;
>>>> using System.Data;
>>>> using System.Drawing;
>>>> using System.Linq;
>>>> using System.Text;
>>>> using System.Threading;
>>>> using System.Windows.Forms;
>>>>
>>>> namespace WindowsFormsApplication1
>>>> {
>>>>     public partial class Form1 : Form
>>>>     {
>>>>         private static readonly log4net.ILog _log =
>>>> log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
>>>>         public Form1()
>>>>         {
>>>>             InitializeComponent();
>>>>         }
>>>>
>>>>         private void button1_Click(object sender, EventArgs e)
>>>>         {
>>>>             while (true)
>>>>             {
>>>>                 _log.Info(DateTime.Now.ToLongTimeString());
>>>>                 Thread.Sleep(1000 * 10);
>>>>             }
>>>>         }
>>>>     }
>>>> }
>>>>
>>>>
>>>> I can see the remoting listener start but a connection is never made.
>>>> The
>>>> server is generating the messages, I can see then on the event log. Any
>>>> ideas?
>>>>
>>>> Cheers,
>>>>
>>>> PP
>>>>
>>>>   
>>>> ------------------------------------------------------------------------
>>>>
>>>>
>>>> No virus found in this incoming message.
>>>> Checked by AVG - www.avg.com 
>>>> Version: 8.5.339 / Virus Database: 270.12.33/2120 - Release Date:
>>>> 05/18/09 06:28:00
>>>>
>>>>   
>>>>       
>>>
>>>     
>>
>>   
>> ------------------------------------------------------------------------
>>
>>
>> No virus found in this incoming message.
>> Checked by AVG - www.avg.com 
>> Version: 8.5.339 / Virus Database: 270.12.33/2120 - Release Date:
>> 05/18/09 06:28:00
>>
>>   
> 
> 
> 

--

-- 
View this message in context: http://www.nabble.com/Remote-Appender-tp23605546p23607862.html
Sent from the Log4net - Users mailing list archive at Nabble.com.

Loren Keagle | 19 May 2009 07:37

Re: Remote Appender

Sorry about the terminology confusion.  In client/server programming, 
the convention is that the client is the object that initiates the 
connection.  In .Net remoting, the conventional terminology is that you 
have an object that 'sources' data, and an object that 'sinks' data.  In 
this case, the source is considered a client, because it initiates the 
connection to the sink, which is considered a server.

This has nothing to do with whether your application itself is a server 
or a client or a word processor, etc.  From log4net's perspective, you 
have a source (client) of logging events, and a sink (server) which is 
receiving events.  In my particular use case, I used remoting because I 
have several dozen embedded machines with no local resources, so they 
all send their logging information to a remote logging server.  Some 
people use the remote syslog appender for this, but I needed the 
flexibility of handling the logging events myself, and setting log 
levels for each remote client.

As far as the logging itself is concerned, the appender works exactly 
the same as the console appender, in that if you set it to INFO, only 
INFO level events and higher will be sent over the remoting pipe.  You 
should not change any of your logging code just to add another 
appender.  It's one of the benefits of the log4net architecture.  Now 
what you do with the events on the sink is completely up to you.  My use 
case was to build a remote logger because I couldn't log locally, so I 
simply take the events and send them to, surprise, another log4net instance!

client --(log.Info)--> RemotingAppender ----|
client --(log.Info)--> RemotingAppender ----|
client --(log.Info)--> RemotingAppender ----|---> (Network) --> logging 
server --(log.Info)--> FileAppender
client --(log.Info)--> RemotingAppender ----|
client --(log.Info)--> RemotingAppender ----|

~Loren

ppden wrote:
> Thanks again for your help. But now I am at a bit of a loss. If the sink
> class on the server side or on the client? I assume it was on the client
> side, but as per you code it appears to be on the server side.
>
> Also, I notice that you are not using the same pattern I use to log events.
> I just use the basic log.Info(...) and the reason I though it would be a
> good idea to use the remote appender is because I don't have to change the
> code (over 2 milion lines of code with lots of log.info) and handle
> everything by adding the new appender to the configuration file. Am I
> completely wrong? 
>
>
> Loren Keagle wrote:
>   
>> I did not alter the connection functionality at all.  I simply added a 
>> timer: to the log4net 1.2.10 RemotingAppender as follows:
>>
>>
>> public class TimedRemotingAppender : RemotingAppender
>>     {
>>         public TimedRemotingAppender()
>>         {
>>             FlushPeriod = 10; // seconds
>>             timer = new Timer(FlushBuffer);
>>         }
>>
>>         /// <summary>
>>         /// The period, in seconds, at which the buffer is sent 
>> regardless of being full
>>         /// </summary>
>>         public int FlushPeriod { get; set; }
>>
>>         private readonly Timer timer;
>>         private void FlushBuffer(object state) { Flush(); }
>>
>>         protected override void Append(LoggingEvent loggingEvent)
>>         {
>>             base.Append(loggingEvent);
>>             timer.Change(FlushPeriod * 1000, Timeout.Infinite);
>>         }
>>     }
>>
>> Which is configured the same as the RemotingAppender:
>>
>>     <appender name="RemotingAppender" 
>> type="APS.Gate.TimedRemotingAppender" >
>>       <sink value="tcp://localhost:9250/LoggingSink" />
>>       <bufferSize value="100" />
>>       <flushPeriod>20</flushPeriod>
>>     </appender>
>>
>>
>> My server implementation is also trivially simple:
>>
>> public class RemotingLogger : MarshalByRefObject, 
>> RemotingAppender.IRemoteLoggingSink
>>     {
>>         private static readonly ILog logger = 
>> LogManager.GetLogger(typeof(RemotingLogger));
>>
>>         public void LogEvents(LoggingEvent[] events)
>>         {
>>             if (events == null) return;
>>             lock (this)
>>             {
>>                 foreach (LoggingEvent le in events)
>>                 {
>>                     logger.Logger.Log(le);
>>                 }
>>             }
>>         }
>>     }
>>
>> All that is required for me is to add the following code to your remote 
>> event sink:
>>
>> TcpServerChannel channel = new 
>> TcpServerChannel(Settings.Default.RemotingPort);
>> ChannelServices.RegisterChannel(channel, false);
>> RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingLogger), 
>> "LoggingSink", WellKnownObjectMode.Singleton);
>>
>>
>> This works fine for me.  Perhaps you have a firewall issue?  My example 
>> is for source and sink on the same machine.  If the sink is on a 
>> different machine, you'll need to open up your firewall for the port you 
>> decide to use.
>>
>> ~Loren
>>
>>
>>     

Karim Bourouba | 19 May 2009 17:24
Picon
Favicon

SystemNullReferenceException usgin log4net with MySql

Hi There,
 
I have been working with log4net now for a few weeks, after some work I have managed to use the ADONetAppender to log to a MySQL DB. However, although I can get messages into my DB, I am getting the following error on my console:
 

 
log4net:ERROR [AdoNetAppender] Could not open database connection []
System.ArgumentNullException: Key cannot be null.
Parameter name: key
   at System.Collections.Hashtable.get_Item(Object key)
   at MySql.Data.MySqlClient.MySqlPoolManager.GetPool(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at log4net.Appender.AdoNetAppender.InitializeDatabaseConnection()
log4net:ERROR [AdoNetAppender] Could not open database connection []
System.ArgumentNullException: Key cannot be null.
Parameter name: key
   at System.Collections.Hashtable.get_Item(Object key)
   at MySql.Data.MySqlClient.MySqlPoolManager.GetPool(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at log4net.Appender.AdoNetAppender.InitializeDatabaseConnection()
 
The code for logging to my DB is as follows:
 
using log4net;
using log4net.Appender;
using log4net.Repository.Hierarchy;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Text;
namespace BGCPLogger.LogSetup
{

public class SetUpLog
{
internal readonly ILog _log = LogManager.GetLogger(typeof(SetUpLog));
/*****************************************************************************/

internal SetUpLog()
{
log4net.Config.XmlConfigurator.Configure();
}
/*****************************************************************************/

public SetUpLog(string dbConn)
{
log4net.Config.XmlConfigurator.Configure();
createAdoSettings(dbConn);
}
/*****************************************************************************/

private Hierarchy hierachy()
{
Hierarchy h = (Hierarchy)log4net.LogManager.GetRepository();
return h;
}
/*****************************************************************************/

private AdoNetAppender adoAppender()
{
Hierarchy myHierarchy = hierachy();
if (myHierarchy != null)
{
AdoNetAppender adoApp = (AdoNetAppender)myHierarchy.Root.GetAppender("ADONetAppender");
return adoApp;
}
return null;
}
/*****************************************************************************/

private void createAdoSettings(string dbConn)
{
AdoNetAppender myAppender = adoAppender();
if (myAppender != null)
{
myAppender.ConnectionString = dbConn;
myAppender.UseTransactions = true;
myAppender.ActivateOptions();
}
}
}
}

My log4net section in my app.config looks like this:
 
<log4net>
<root>
<level value="INFO" />
<appender-ref ref="ColoredConsoleAppender" />
<appender-ref ref="ADONetAppender" />
</root>
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
<bufferSize value="1" />
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
<commandText value="insert into `tbl_lg_mlog_task_logs`(mlog_lastuser,mlog_thread,mlog_level,mlog_logger,mlog_message,mlog_exception)values('',?thread,?log_level,'My Log',?message,?exception)" />
<parameter>
<parameterName value="?thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%t" />
</layout>
</parameter>
<parameter>
<parameterName value="?log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%p" />
</layout>
</parameter>
<parameter>
<parameterName value="?logger" />
<dbType value="String" />
<size value="512" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%c" />
</layout>
</parameter>
<parameter>
<parameterName value="?host" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%X{host}" />
</layout>
</parameter>
<parameter>
<parameterName value="?message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%m" />
</layout>
</parameter>
<parameter>
<parameterName value="?exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<appender name="LogFileAppender"
type="log4net.Appender.FileAppender" >
<param name="File" value="C:\log-file.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header]\r\n"/>
<param name="Footer" value="[Footer]\r\n"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="DEBUG" />
<param name="LevelMax" value="WARN" />
</filter>
</appender>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender" >
<mapping>
<level value="INFO" />
<foreColor value="Green, HighIntensity" />
</mapping>
<mapping>
<level value="Warn" />
<foreColor value="Cyan, HighIntensity" />
</mapping>
<mapping>
<level value="Fatal" />
<foreColor value="Red, HighIntensity" />
</mapping>
<mapping>
<level value="Error" />
<foreColor value="Yellow, HighIntensity" />
</mapping>
<mapping>
<level value="Debug" />
<foreColor value="Cyan, HighIntensity" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header]\r\n" />
<param name="Footer" value="[Footer]\r\n" />
<param name="ConversionPattern" value="%d [%t] %-5p %m%n" />
</layout>
</appender>
</log4net>
 
I am sure this is a fairly simple thing to fix, right now I am assuming that it is just some missing configuration. If anyone could shed some light on this, I would be very greatful.
 
BR



" Upgrade to Internet Explorer 8 Optimised for MSN. " Download Now
stefan.moser | 19 May 2009 23:09
Picon

Log not logging in custom filter


I'm writing a custom filter (inherits from FilterSkeleton) and I want to log
errors inside the filter.  The problem is that any log events created inside
the filter is not getting logged.  Is there a special restriction that log
events cannot be created this far down inside the loggin pipeline?

public override FilterDecision Decide(LoggingEvent loggingEvent)
{
    // Do the interesting stuff

    // In some exceptional case, log an error
    LogManager.GetLogger("TheLogger").Error("log message", exception);
}

Any reason why this code wouldn't work?
--

-- 
View this message in context: http://www.nabble.com/Log-not-logging-in-custom-filter-tp23624032p23624032.html
Sent from the Log4net - Users mailing list archive at Nabble.com.


Gmane