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.