nicko       2005/08/29 12:45:31

  Modified:    src/Appender AppenderSkeleton.cs
                        BufferingAppenderSkeleton.cs
                        BufferingForwardingAppender.cs FileAppender.cs
                        ForwardingAppender.cs RollingFileAppender.cs
                        TextWriterAppender.cs
               examples/net/1.0/Appenders/SampleAppendersApp/cs/src/Appender
                        AsyncAppender.cs
               src      log4net.csproj
               src/Util AppenderAttachedImpl.cs
  Added:       src/Appender IBulkAppender.cs
  Log:
  Fix for LOG4NET-46. Added IBulkAppender interface. Added implementation to 
AppenderSkeleton and subclasses
  
  Revision  Changes    Path
  1.7       +182 -22   logging-log4net/src/Appender/AppenderSkeleton.cs
  
  Index: AppenderSkeleton.cs
  ===================================================================
  RCS file: /home/cvs/logging-log4net/src/Appender/AppenderSkeleton.cs,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AppenderSkeleton.cs       14 Feb 2005 19:45:11 -0000      1.6
  +++ AppenderSkeleton.cs       29 Aug 2005 19:45:30 -0000      1.7
  @@ -18,6 +18,7 @@
   

   using System;

   using System.IO;

  +using System.Collections;

   

   using log4net.Filter;

   using log4net.Util;

  @@ -42,7 +43,7 @@
        /// </remarks>

        /// <author>Nicko Cadell</author>

        /// <author>Gert Driesen</author>

  -     public abstract class AppenderSkeleton : IAppender, IOptionHandler

  +     public abstract class AppenderSkeleton : IAppender, IBulkAppender, 
IOptionHandler

        {

                #region Protected Instance Constructors

   

  @@ -247,7 +248,7 @@
                /// <summary>

                /// Performs threshold checks and invokes filters before 

                /// delegating actual logging to the subclasses specific 

  -             /// <see cref="AppenderSkeleton.Append"/> method.

  +             /// <see cref="AppenderSkeleton.Append(LoggingEvent)"/> method.

                /// </summary>

                /// <param name="loggingEvent">The event to log.</param>

                /// <remarks>

  @@ -310,43 +311,120 @@
                                {

                                        m_recursiveGuard = true;

   

  -                                     if 
(!IsAsSevereAsThreshold(loggingEvent.Level)) 

  +                                     if (FilterEvent(loggingEvent) && 
PreAppendCheck())

                                        {

  -                                             return;

  +                                             this.Append(loggingEvent);

                                        }

  +                             }

  +                             catch(Exception ex)

  +                             {

  +                                     ErrorHandler.Error("Failed in 
DoAppend", ex);

  +                             }

  +                             catch

  +                             {

  +                                     // Catch handler for non 
System.Exception types

  +                                     ErrorHandler.Error("Failed in DoAppend 
(unknown exception)");

  +                             }

  +                             finally

  +                             {

  +                                     m_recursiveGuard = false;

  +                             }

  +                     }

  +             }

  +

  +             #endregion Implementation of IAppender

  +

  +             #region Implementation of IBulkAppender

  +

  +             /// <summary>

  +             /// Performs threshold checks and invokes filters before 

  +             /// delegating actual logging to the subclasses specific 

  +             /// <see cref="AppenderSkeleton.Append(LoggingEvent[])"/> 
method.

  +             /// </summary>

  +             /// <param name="loggingEvents">The array of events to 
log.</param>

  +             /// <remarks>

  +             /// <para>

  +             /// This method cannot be overridden by derived classes. A

  +             /// derived class should override the <see cref="Append"/> 
method

  +             /// which is called by this method.

  +             /// </para>

  +             /// <para>

  +             /// The implementation of this method is as follows:

  +             /// </para>

  +             /// <para>

  +             /// <list type="bullet">

  +             ///             <item>

  +             ///                     <description>

  +             ///                     Checks that the severity of the 
<paramref name="loggingEvent"/>

  +             ///                     is greater than or equal to the <see 
cref="Threshold"/> of this

  +             ///                     appender.</description>

  +             ///             </item>

  +             ///             <item>

  +             ///                     <description>

  +             ///                     Checks that the <see cref="Filter"/> 
chain accepts the 

  +             ///                     <paramref name="loggingEvent"/>.

  +             ///                     </description>

  +             ///             </item>

  +             ///             <item>

  +             ///                     <description>

  +             ///                     Calls <see cref="PreAppendCheck()"/> 
and checks that 

  +             ///                     it returns <c>true</c>.</description>

  +             ///             </item>

  +             /// </list>

  +             /// </para>

  +             /// <para>

  +             /// If all of the above steps succeed then the <paramref 
name="loggingEvents"/>

  +             /// will be passed to the <see cref="Append"/> method.

  +             /// </para>

  +             /// </remarks>

  +             public void DoAppend(LoggingEvent[] loggingEvents) 

  +             {

  +                     // This lock is absolutely critical for correct 
formatting

  +                     // of the message in a multi-threaded environment.  
Without

  +                     // this, the message may be broken up into elements from

  +                     // multiple thread contexts (like get the wrong thread 
ID).

   

  -                                     IFilter f = this.FilterHead;

  +                     lock(this)

  +                     {

  +                             if (m_closed)

  +                             {

  +                                     ErrorHandler.Error("Attempted to append 
to closed appender named ["+m_name+"].");

  +                                     return;

  +                             }

   

  -                                     while(f != null) 

  +                             // prevent re-entry

  +                             if (m_recursiveGuard)

  +                             {

  +                                     return;

  +                             }

  +

  +                             try

  +                             {

  +                                     m_recursiveGuard = true;

  +

  +                                     ArrayList filteredEvents = new 
ArrayList(loggingEvents.Length);

  +

  +                                     foreach(LoggingEvent loggingEvent in 
loggingEvents)

                                        {

  -                                             switch(f.Decide(loggingEvent)) 

  +                                             if (FilterEvent(loggingEvent))

                                                {

  -                                                     case 
FilterDecision.Deny: 

  -                                                             return;         
// Return without appending

  -

  -                                                     case 
FilterDecision.Accept:

  -                                                             f = null;       
// Break out of the loop

  -                                                             break;

  -

  -                                                     case 
FilterDecision.Neutral:

  -                                                             f = f.Next;     
// Move to next filter

  -                                                             break;

  +                                                     
filteredEvents.Add(loggingEvent);

                                                }

                                        }

   

  -                                     if (PreAppendCheck())

  +                                     if (filteredEvents.Count > 0 && 
PreAppendCheck())

                                        {

  -                                             this.Append(loggingEvent);

  +                                             
this.Append((LoggingEvent[])filteredEvents.ToArray(typeof(LoggingEvent)));

                                        }

                                }

                                catch(Exception ex)

                                {

  -                                     ErrorHandler.Error("Failed in 
DoAppend", ex);

  +                                     ErrorHandler.Error("Failed in Bulk 
DoAppend", ex);

                                }

                                catch

                                {

                                        // Catch handler for non 
System.Exception types

  -                                     ErrorHandler.Error("Failed in DoAppend 
(unknown exception)");

  +                                     ErrorHandler.Error("Failed in Bulk 
DoAppend (unknown exception)");

                                }

                                finally

                                {

  @@ -355,7 +433,67 @@
                        }

                }

   

  -             #endregion Implementation of IAppender

  +             #endregion Implementation of IBulkAppender

  +

  +             /// <summary>

  +             /// Test if the logging event should we output by this appender

  +             /// </summary>

  +             /// <param name="loggingEvent">the event to test</param>

  +             /// <returns><c>true</c> if the event should be output, 
<c>false</c> if the event should be ignored</returns>

  +             /// <remarks>

  +             /// <para>

  +             /// This method checks the logging event against the threshold 
level set

  +             /// on this appender and also against the filters specified on 
this

  +             /// appender.

  +             /// </para>

  +             /// <para>

  +             /// The implementation of this method is as follows:

  +             /// </para>

  +             /// <para>

  +             /// <list type="bullet">

  +             ///             <item>

  +             ///                     <description>

  +             ///                     Checks that the severity of the 
<paramref name="loggingEvent"/>

  +             ///                     is greater than or equal to the <see 
cref="Threshold"/> of this

  +             ///                     appender.</description>

  +             ///             </item>

  +             ///             <item>

  +             ///                     <description>

  +             ///                     Checks that the <see cref="Filter"/> 
chain accepts the 

  +             ///                     <paramref name="loggingEvent"/>.

  +             ///                     </description>

  +             ///             </item>

  +             /// </list>

  +             /// </para>

  +             /// </remarks>

  +             virtual protected bool FilterEvent(LoggingEvent loggingEvent)

  +             {

  +                     if (!IsAsSevereAsThreshold(loggingEvent.Level)) 

  +                     {

  +                             return false;

  +                     }

  +

  +                     IFilter f = this.FilterHead;

  +

  +                     while(f != null) 

  +                     {

  +                             switch(f.Decide(loggingEvent)) 

  +                             {

  +                                     case FilterDecision.Deny: 

  +                                             return false;   // Return 
without appending

  +

  +                                     case FilterDecision.Accept:

  +                                             f = null;               // 
Break out of the loop

  +                                             break;

  +

  +                                     case FilterDecision.Neutral:

  +                                             f = f.Next;             // Move 
to next filter

  +                                             break;

  +                             }

  +                     }

  +

  +                     return true;

  +             }

   

                #region Public Instance Methods

   

  @@ -464,6 +602,28 @@
                abstract protected void Append(LoggingEvent loggingEvent);

   

                /// <summary>

  +             /// Append a bulk array of logging events.

  +             /// </summary>

  +             /// <param name="loggingEvents">the array of logging 
events</param>

  +             /// <remarks>

  +             /// <para>

  +             /// This base class implementation calls the <see 
cref="Append(LoggingEvent)"/>

  +             /// method for each element in the bulk array.

  +             /// </para>

  +             /// <para>

  +             /// A sub class that can better process a bulk array of events 
should

  +             /// override this method in addition to <see 
cref="Append(LoggingEvent)"/>.

  +             /// </para>

  +             /// </remarks>

  +             virtual protected void Append(LoggingEvent[] loggingEvents)

  +             {

  +                     foreach(LoggingEvent loggingEvent in loggingEvents)

  +                     {

  +                             Append(loggingEvent);

  +                     }

  +             }

  +

  +             /// <summary>

                /// Called before <see cref="Append"/> as a precondition.

                /// </summary>

                /// <remarks>

  
  
  
  1.11      +51 -21    logging-log4net/src/Appender/BufferingAppenderSkeleton.cs
  
  Index: BufferingAppenderSkeleton.cs
  ===================================================================
  RCS file: 
/home/cvs/logging-log4net/src/Appender/BufferingAppenderSkeleton.cs,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- BufferingAppenderSkeleton.cs      8 Jun 2005 17:13:39 -0000       1.10
  +++ BufferingAppenderSkeleton.cs      29 Aug 2005 19:45:30 -0000      1.11
  @@ -17,6 +17,7 @@
   #endregion

   

   using System;

  +using System.Collections;

   

   using log4net.Util;

   using log4net.Core;

  @@ -286,7 +287,7 @@
                                // really be checking for.

                                if (m_cb != null && m_bufferSize > 1 && 
!m_lossy)

                                {

  -                                     SendBuffer(m_cb);

  +                                     SendFromBuffer(null, m_cb);

                                }

                        }

                }

  @@ -355,18 +356,26 @@
                                {

                                        if (m_lossyEvaluator != null)

                                        {

  -                                             foreach(LoggingEvent 
loggingEvent in m_cb.PopAll())

  +                                             LoggingEvent[] bufferedEvents = 
m_cb.PopAll();

  +                                             ArrayList filteredEvents = new 
ArrayList(bufferedEvents.Length);

  +

  +                                             foreach(LoggingEvent 
loggingEvent in bufferedEvents)

                                                {

                                                        if 
(m_lossyEvaluator.IsTriggeringEvent(loggingEvent))

                                                        {

  -                                                             SendBuffer(new 
LoggingEvent[] { loggingEvent } );

  +                                                             
filteredEvents.Add(loggingEvent);

                                                        }

                                                }

  +

  +                                             if (filteredEvents.Count > 0)

  +                                             {

  +                                                     
SendBuffer((LoggingEvent[])filteredEvents.ToArray(typeof(LoggingEvent)));

  +                                             }

                                        }

                                }

                                else

                                {

  -                                     SendBuffer(m_cb);

  +                                     SendFromBuffer(null, m_cb);

                                }

                        }

                }

  @@ -437,21 +446,26 @@
                                        if (!m_lossy)

                                        {

                                                // Not lossy, must send all 
events

  -                                             SendBuffer(new LoggingEvent[] { 
discardedLoggingEvent } );

  -                                             SendBuffer(m_cb);

  +                                             
SendFromBuffer(discardedLoggingEvent, m_cb);

                                        }

                                        else

                                        {

  -                                             // Check if the discarded event 
should be logged

  -                                             if (m_lossyEvaluator != null && 
m_lossyEvaluator.IsTriggeringEvent(discardedLoggingEvent))

  +                                             // Check if the discarded event 
should not be logged

  +                                             if (m_lossyEvaluator == null || 
!m_lossyEvaluator.IsTriggeringEvent(discardedLoggingEvent))

                                                {

  -                                                     SendBuffer(new 
LoggingEvent[] { discardedLoggingEvent } );

  +                                                     // Clear the discarded 
event as we should not forward it

  +                                                     discardedLoggingEvent = 
null;

                                                }

   

                                                // Check if the event should 
trigger the whole buffer to be sent

                                                if (m_evaluator != null && 
m_evaluator.IsTriggeringEvent(loggingEvent))

                                                {

  -                                                     SendBuffer(m_cb);

  +                                                     
SendFromBuffer(discardedLoggingEvent, m_cb);

  +                                             }

  +                                             else if (discardedLoggingEvent 
!= null)

  +                                             {

  +                                                     // Just send the 
discarded event

  +                                                     SendBuffer(new 
LoggingEvent[] { discardedLoggingEvent } );

                                                }

                                        }

                                }

  @@ -462,7 +476,7 @@
                                        // Check if the event should trigger 
the whole buffer to be sent

                                        if (m_evaluator != null && 
m_evaluator.IsTriggeringEvent(loggingEvent))

                                        {

  -                                             SendBuffer(m_cb);

  +                                             SendFromBuffer(null, m_cb);

                                        }

                                }

                        }

  @@ -475,29 +489,45 @@
                /// <summary>

                /// Sends the contents of the buffer.

                /// </summary>

  +             /// <param name="firstLoggingEvent">The first logging 
event.</param>

                /// <param name="buffer">The buffer containing the events that 
need to be send.</param>

                /// <remarks>

  -             /// The subclass must override either <see 
cref="SendBuffer(CyclicBuffer)"/>

  -             /// or <see cref="SendBuffer(LoggingEvent[])"/>.

  +             /// The subclass must override <see 
cref="SendBuffer(LoggingEvent[])"/>.

                /// </remarks>

  -             virtual protected void SendBuffer(CyclicBuffer buffer)

  +             virtual protected void SendFromBuffer(LoggingEvent 
firstLoggingEvent, CyclicBuffer buffer)

                {

  -                     SendBuffer(buffer.PopAll());

  +                     LoggingEvent[] bufferEvents = buffer.PopAll();

  +

  +                     if (firstLoggingEvent == null)

  +                     {

  +                             SendBuffer(bufferEvents);

  +                     }

  +                     else if (bufferEvents.Length == 0)

  +                     {

  +                             SendBuffer(new LoggingEvent[] { 
firstLoggingEvent } );

  +                     }

  +                     else

  +                     {

  +                             // Create new array with the firstLoggingEvent 
at the head

  +                             LoggingEvent[] events = new 
LoggingEvent[bufferEvents.Length + 1];

  +                             Array.Copy(bufferEvents, 0, events, 1, 
bufferEvents.Length);

  +                             events[0] = firstLoggingEvent;

  +

  +                             SendBuffer(events);

  +                     }

                }

   

  +             #endregion Protected Instance Methods

  +

                /// <summary>

                /// Sends the events.

                /// </summary>

                /// <param name="events">The events that need to be 
send.</param>

                /// <remarks>

  -             /// The subclass must override either <see 
cref="SendBuffer(CyclicBuffer)"/>

  -             /// or <see cref="SendBuffer(LoggingEvent[])"/>.

  +             /// The subclass must override this method to process the 
buffered events.

                /// </remarks>

  -             virtual protected void SendBuffer(LoggingEvent[] events)

  -             {

  -             }

  +             abstract protected void SendBuffer(LoggingEvent[] events);

   

  -             #endregion Protected Instance Methods

   

                #region Private Static Fields

   

  
  
  
  1.7       +1 -5      
logging-log4net/src/Appender/BufferingForwardingAppender.cs
  
  Index: BufferingForwardingAppender.cs
  ===================================================================
  RCS file: 
/home/cvs/logging-log4net/src/Appender/BufferingForwardingAppender.cs,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- BufferingForwardingAppender.cs    17 Jan 2005 20:18:41 -0000      1.6
  +++ BufferingForwardingAppender.cs    29 Aug 2005 19:45:30 -0000      1.7
  @@ -106,11 +106,7 @@
                        // Pass the logging event on to the attached appenders

                        if (m_appenderAttachedImpl != null)

                        {

  -                             // Send each event one at a time

  -                             foreach(LoggingEvent e in events)

  -                             {

  -                                     
m_appenderAttachedImpl.AppendLoopOnAppenders(e);

  -                             }

  +                             
m_appenderAttachedImpl.AppendLoopOnAppenders(events);

                        }

                }

   

  
  
  
  1.20      +26 -0     logging-log4net/src/Appender/FileAppender.cs
  
  Index: FileAppender.cs
  ===================================================================
  RCS file: /home/cvs/logging-log4net/src/Appender/FileAppender.cs,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- FileAppender.cs   21 Mar 2005 00:23:13 -0000      1.19
  +++ FileAppender.cs   29 Aug 2005 19:45:30 -0000      1.20
  @@ -839,6 +839,32 @@
                }

   

                /// <summary>

  +             /// This method is called by the <see 
cref="AppenderSkeleton.DoAppend"/>

  +             /// method. 

  +             /// </summary>

  +             /// <param name="loggingEvents">The array of events to 
log.</param>

  +             /// <remarks>

  +             /// <para>

  +             /// Acquires the output file locks once before writing all the 
events to

  +             /// the stream.

  +             /// </para>

  +             /// </remarks>

  +             override protected void Append(LoggingEvent[] loggingEvents) 

  +             {

  +                     if (m_stream.AcquireLock())

  +                     {

  +                             try

  +                             {

  +                                     base.Append(loggingEvents);

  +                             }

  +                             finally

  +                             {

  +                                     m_stream.ReleaseLock();

  +                             }

  +                     }

  +             }

  +

  +             /// <summary>

                /// Writes a footer as produced by the embedded layout's <see 
cref="ILayout.Footer"/> property.

                /// </summary>

                /// <remarks>

  
  
  
  1.7       +19 -1     logging-log4net/src/Appender/ForwardingAppender.cs
  
  Index: ForwardingAppender.cs
  ===================================================================
  RCS file: /home/cvs/logging-log4net/src/Appender/ForwardingAppender.cs,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ForwardingAppender.cs     17 Jan 2005 20:18:41 -0000      1.6
  +++ ForwardingAppender.cs     29 Aug 2005 19:45:30 -0000      1.7
  @@ -80,7 +80,7 @@
                }

   

                /// <summary>

  -             /// Append the logging event. 

  +             /// Forward the logging event to the attached appenders 

                /// </summary>

                /// <param name="loggingEvent">The event to log.</param>

                /// <remarks>

  @@ -97,6 +97,24 @@
                        }

                } 

   

  +             /// <summary>

  +             /// Forward the logging events to the attached appenders 

  +             /// </summary>

  +             /// <param name="loggingEvents">The array of events to 
log.</param>

  +             /// <remarks>

  +             /// <para>

  +             /// Delivers the logging events to all the attached appenders.

  +             /// </para>

  +             /// </remarks>

  +             override protected void Append(LoggingEvent[] loggingEvents) 

  +             {

  +                     // Pass the logging event on the the attached appenders

  +                     if (m_appenderAttachedImpl != null)

  +                     {

  +                             
m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvents);

  +                     }

  +             } 

  +

                #endregion Override implementation of AppenderSkeleton

   

                #region Implementation of IAppenderAttachable

  
  
  
  1.24      +35 -5     logging-log4net/src/Appender/RollingFileAppender.cs
  
  Index: RollingFileAppender.cs
  ===================================================================
  RCS file: /home/cvs/logging-log4net/src/Appender/RollingFileAppender.cs,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- RollingFileAppender.cs    14 Aug 2005 21:41:19 -0000      1.23
  +++ RollingFileAppender.cs    29 Aug 2005 19:45:30 -0000      1.24
  @@ -473,13 +473,46 @@
                /// <param name="loggingEvent">the event to write to 
file.</param>

                /// <remarks>

                /// <para>

  -             /// Handles append time behavior for CompositeRollingAppender.  
This checks

  +             /// Handles append time behavior for RollingFileAppender.  This 
checks

                /// if a roll over either by date (checked first) or time 
(checked second)

                /// is need and then appends to the file last.

                /// </para>

                /// </remarks>

                override protected void Append(LoggingEvent loggingEvent) 

                {

  +                     AdjustFileBeforeAppend();

  +                     base.Append(loggingEvent);

  +             }

  +  

  +             /// <summary>

  +             /// Write out an array of logging events.

  +             /// </summary>

  +             /// <param name="loggingEvents">the events to write to 
file.</param>

  +             /// <remarks>

  +             /// <para>

  +             /// Handles append time behavior for RollingFileAppender.  This 
checks

  +             /// if a roll over either by date (checked first) or time 
(checked second)

  +             /// is need and then appends to the file last.

  +             /// </para>

  +             /// </remarks>

  +             override protected void Append(LoggingEvent[] loggingEvents) 

  +             {

  +                     AdjustFileBeforeAppend();

  +                     base.Append(loggingEvents);

  +             }

  +

  +             /// <summary>

  +             /// Performs any required rolling before outputting the next 
event

  +             /// </summary>

  +             /// <remarks>

  +             /// <para>

  +             /// Handles append time behavior for RollingFileAppender.  This 
checks

  +             /// if a roll over either by date (checked first) or time 
(checked second)

  +             /// is need and then appends to the file last.

  +             /// </para>

  +             /// </remarks>

  +             virtual protected void AdjustFileBeforeAppend()

  +             {

                        if (m_rollDate) 

                        {

                                DateTime n = m_dateTime.Now;

  @@ -499,11 +532,8 @@
                                        RollOverSize();

                                }

                        }

  -

  -                     base.Append(loggingEvent);

                }

  -  

  -  

  +

                /// <summary>

                /// Creates and opens the file for logging.  If <see 
cref="StaticLogFileName"/>

                /// is false then the fully qualified name is determined and 
used.

  
  
  
  1.8       +25 -1     logging-log4net/src/Appender/TextWriterAppender.cs
  
  Index: TextWriterAppender.cs
  ===================================================================
  RCS file: /home/cvs/logging-log4net/src/Appender/TextWriterAppender.cs,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- TextWriterAppender.cs     17 Jan 2005 20:18:42 -0000      1.7
  +++ TextWriterAppender.cs     29 Aug 2005 19:45:30 -0000      1.8
  @@ -223,7 +223,31 @@
                        {

                                m_qtw.Flush();

                        } 

  -             } 

  +             }

  +

  +             /// <summary>

  +             /// This method is called by the <see 
cref="AppenderSkeleton.DoAppend"/>

  +             /// method. 

  +             /// </summary>

  +             /// <param name="loggingEvents">The array of events to 
log.</param>

  +             /// <remarks>

  +             /// <para>

  +             /// This method writes all the bulk logged events to the output 
writer

  +             /// before flushing the stream.

  +             /// </para>

  +             /// </remarks>

  +             override protected void Append(LoggingEvent[] loggingEvents) 

  +             {

  +                     foreach(LoggingEvent loggingEvent in loggingEvents)

  +                     {

  +                             RenderLoggingEvent(m_qtw, loggingEvent);

  +                     }

  +

  +                     if (m_immediateFlush) 

  +                     {

  +                             m_qtw.Flush();

  +                     } 

  +             }

   

                /// <summary>

                /// Close this appender instance. The underlying stream or 
writer is also closed.

  
  
  
  1.1                  logging-log4net/src/Appender/IBulkAppender.cs
  
  Index: IBulkAppender.cs
  ===================================================================
  #region Copyright & License

  //

  // Copyright 2001-2005 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

  

  using log4net.Core;

  

  namespace log4net.Appender

  {

        /// <summary>

        /// Interface for appenders that support bulk logging.

        /// </summary>

        /// <remarks>

        /// <para>

        /// This interface extends the <see cref="IAppender"/> interface to

        /// support bulk logging of <see cref="LoggingEvent"/> objects. 
Appenders

        /// should only implement this interface if they can bulk log 
efficiently.

        /// </para>

        /// </remarks>

        /// <author>Nicko Cadell</author>

        public interface IBulkAppender : IAppender

        {

                /// <summary>

                /// Log the array of logging events in Appender specific way.

                /// </summary>

                /// <param name="loggingEvents">The events to log</param>

                /// <remarks>

                /// <para>

                /// This method is called to log an array of events into this 
appender.

                /// </para>

                /// </remarks>

                void DoAppend(LoggingEvent[] loggingEvents);

        }

  }

  
  
  
  1.3       +24 -5     
logging-log4net/examples/net/1.0/Appenders/SampleAppendersApp/cs/src/Appender/AsyncAppender.cs
  
  Index: AsyncAppender.cs
  ===================================================================
  RCS file: 
/home/cvs/logging-log4net/examples/net/1.0/Appenders/SampleAppendersApp/cs/src/Appender/AsyncAppender.cs,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AsyncAppender.cs  15 Jun 2005 16:26:40 -0000      1.2
  +++ AsyncAppender.cs  29 Aug 2005 19:45:31 -0000      1.3
  @@ -33,7 +33,7 @@
        /// This allows the calling thread to be released quickly, however it 
does

        /// not guarantee the ordering of events delivered to the attached 
appenders.

        /// </remarks>

  -     public sealed class AsyncAppender : IAppender, IOptionHandler, 
IAppenderAttachable

  +     public sealed class AsyncAppender : IAppender, IBulkAppender, 
IOptionHandler, IAppenderAttachable

        {

                private string m_name;

   

  @@ -71,13 +71,32 @@
                        System.Threading.ThreadPool.QueueUserWorkItem(new 
WaitCallback(AsyncAppend), loggingEvent);

                }

   

  -             private void AsyncAppend(object state)

  +             public void DoAppend(LoggingEvent[] loggingEvents)

                {

  -                     LoggingEvent loggingEvent = state as LoggingEvent;

  +                     foreach(LoggingEvent loggingEvent in loggingEvents)

  +                     {

  +                             loggingEvent.Fix = m_fixFlags;

  +                     }

  +                     System.Threading.ThreadPool.QueueUserWorkItem(new 
WaitCallback(AsyncAppend), loggingEvents);

  +             }

   

  -                     if (m_appenderAttachedImpl != null && loggingEvent != 
null)

  +             private void AsyncAppend(object state)

  +             {

  +                     if (m_appenderAttachedImpl != null)

                        {

  -                             
m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent);

  +                             LoggingEvent loggingEvent = state as 
LoggingEvent;

  +                             if (loggingEvent != null)

  +                             {

  +                                     
m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent);

  +                             }

  +                             else

  +                             {

  +                                     LoggingEvent[] loggingEvents = state as 
LoggingEvent[];

  +                                     if (loggingEvents != null)

  +                                     {

  +                                             
m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvents);

  +                                     }

  +                             }

                        }

                }

   

  
  
  
  1.19      +5 -0      logging-log4net/src/log4net.csproj
  
  Index: log4net.csproj
  ===================================================================
  RCS file: /home/cvs/logging-log4net/src/log4net.csproj,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- log4net.csproj    14 Feb 2005 03:24:36 -0000      1.18
  +++ log4net.csproj    29 Aug 2005 19:45:31 -0000      1.19
  @@ -193,6 +193,11 @@
                       BuildAction = "Compile"

                   />

                   <File

  +                    RelPath = "Appender\IBulkAppender.cs"

  +                    SubType = "Code"

  +                    BuildAction = "Compile"

  +                />

  +                <File

                       RelPath = "Appender\LocalSyslogAppender.cs"

                       SubType = "Code"

                       BuildAction = "Compile"

  
  
  
  1.7       +82 -0     logging-log4net/src/Util/AppenderAttachedImpl.cs
  
  Index: AppenderAttachedImpl.cs
  ===================================================================
  RCS file: /home/cvs/logging-log4net/src/Util/AppenderAttachedImpl.cs,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AppenderAttachedImpl.cs   31 Jan 2005 22:56:49 -0000      1.6
  +++ AppenderAttachedImpl.cs   29 Aug 2005 19:45:31 -0000      1.7
  @@ -98,8 +98,90 @@
                        return m_appenderList.Count;

                }

   

  +             /// <summary>

  +             /// Append on on all attached appenders.

  +             /// </summary>

  +             /// <param name="loggingEvents">The array of events being 
logged.</param>

  +             /// <returns>The number of appenders called.</returns>

  +             /// <remarks>

  +             /// <para>

  +             /// Calls the <see cref="IAppender.DoAppend" /> method on all 

  +             /// attached appenders.

  +             /// </para>

  +             /// </remarks>

  +             public int AppendLoopOnAppenders(LoggingEvent[] loggingEvents) 

  +             {

  +                     if (loggingEvents == null)

  +                     {

  +                             throw new 
ArgumentNullException("loggingEvents");

  +                     }

  +                     if (loggingEvents.Length == 0)

  +                     {

  +                             throw new ArgumentException("loggingEvents 
array must not be empty", "loggingEvents");

  +                     }

  +                     if (loggingEvents.Length == 1)

  +                     {

  +                             // Fall back to single event path

  +                             return AppendLoopOnAppenders(loggingEvents[0]);

  +                     }

  +

  +                     // m_appenderList is null when empty

  +                     if (m_appenderList == null) 

  +                     {

  +                             return 0;

  +                     }

  +

  +                     if (m_appenderArray == null)

  +                     {

  +                             m_appenderArray = m_appenderList.ToArray();

  +                     }

  +

  +                     foreach(IAppender appender in m_appenderArray)

  +                     {

  +                             try

  +                             {

  +                                     CallAppend(appender, loggingEvents);

  +                             }

  +                             catch(Exception ex)

  +                             {

  +                                     LogLog.Error("AppenderAttachedImpl: 
Failed to append to appender [" + appender.Name + "]", ex);

  +                             }

  +                     }

  +                     return m_appenderList.Count;

  +             }

  +

                #endregion Public Instance Methods

   

  +             /// <summary>

  +             /// Calls the DoAppende method on the <see cref="IAppender"/> 
with 

  +             /// the <see cref="LoggingEvent"/> objects supplied.

  +             /// </summary>

  +             /// <param name="appender">The appender</param>

  +             /// <param name="loggingEvents">The events</param>

  +             /// <remarks>

  +             /// <para>

  +             /// If the <paramref name="appender" /> supports the <see 
cref="IBulkAppender"/>

  +             /// interface then the <paramref name="loggingEvents" /> will 
be passed 

  +             /// through using that interface. Otherwise the <see 
cref="LoggingEvent"/>

  +             /// objects in the array will be passed one at a time.

  +             /// </para>

  +             /// </remarks>

  +             private static void CallAppend(IAppender appender, 
LoggingEvent[] loggingEvents)

  +             {

  +                     IBulkAppender bulkAppender = appender as IBulkAppender;

  +                     if (bulkAppender != null)

  +                     {

  +                             bulkAppender.DoAppend(loggingEvents);

  +                     }

  +                     else

  +                     {

  +                             foreach(LoggingEvent loggingEvent in 
loggingEvents)

  +                             {

  +                                     appender.DoAppend(loggingEvent);

  +                             }

  +                     }

  +             }

  +

                #region Implementation of IAppenderAttachable

   

                /// <summary>

  
  
  

Reply via email to