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.

Reply via email to