You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by bo...@apache.org on 2016/10/16 10:32:50 UTC
svn commit: r1765136 - in /logging/log4net/trunk/src: ./ Appender/
Repository/
Author: bodewig
Date: Sun Oct 16 10:32:49 2016
New Revision: 1765136
URL: http://svn.apache.org/viewvc?rev=1765136&view=rev
Log:
LOG4NET-511 Implement flushing of appenders that buffer data
Patch by @JJoe2
closes #37
Added:
logging/log4net/trunk/src/Appender/IFlushable.cs (with props)
Modified:
logging/log4net/trunk/src/Appender/BufferingAppenderSkeleton.cs
logging/log4net/trunk/src/Appender/DebugAppender.cs
logging/log4net/trunk/src/Appender/RemotingAppender.cs
logging/log4net/trunk/src/Appender/TextWriterAppender.cs
logging/log4net/trunk/src/Appender/TraceAppender.cs
logging/log4net/trunk/src/LogManager.cs
logging/log4net/trunk/src/Repository/LoggerRepositorySkeleton.cs
logging/log4net/trunk/src/log4net.vs2008.csproj
logging/log4net/trunk/src/log4net.vs2010.csproj
logging/log4net/trunk/src/log4net.vs2012.csproj
Modified: logging/log4net/trunk/src/Appender/BufferingAppenderSkeleton.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/BufferingAppenderSkeleton.cs?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/Appender/BufferingAppenderSkeleton.cs (original)
+++ logging/log4net/trunk/src/Appender/BufferingAppenderSkeleton.cs Sun Oct 16 10:32:49 2016
@@ -68,7 +68,7 @@ namespace log4net.Appender
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public abstract class BufferingAppenderSkeleton : AppenderSkeleton
+ public abstract class BufferingAppenderSkeleton : AppenderSkeleton, IFlushable
{
#region Protected Instance Constructors
@@ -261,6 +261,17 @@ namespace log4net.Appender
#region Public Methods
+ /// <summary>
+ /// Flushes any buffered log data.
+ /// </summary>
+ /// <param name="millisecondsTimeout">The maximum time to wait for logging events to be flushed.</param>
+ /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
+ public virtual bool Flush(int millisecondsTimeout)
+ {
+ Flush();
+ return true;
+ }
+
/// <summary>
/// Flush the currently buffered events
/// </summary>
Modified: logging/log4net/trunk/src/Appender/DebugAppender.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/DebugAppender.cs?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/Appender/DebugAppender.cs (original)
+++ logging/log4net/trunk/src/Appender/DebugAppender.cs Sun Oct 16 10:32:49 2016
@@ -40,7 +40,7 @@ namespace log4net.Appender
/// </para>
/// </remarks>
/// <author>Nicko Cadell</author>
- public class DebugAppender : AppenderSkeleton
+ public class DebugAppender : AppenderSkeleton, IFlushable
{
#region Public Instance Constructors
@@ -102,6 +102,23 @@ namespace log4net.Appender
#endregion Public Instance Properties
+
+ /// <summary>
+ /// Flushes any buffered log data.
+ /// </summary>
+ /// <param name="millisecondsTimeout">The maximum time to wait for logging events to be flushed.</param>
+ /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
+ public bool Flush(int millisecondsTimeout)
+ {
+ // Nothing to do if ImmediateFlush is true
+ if (m_immediateFlush) return true;
+
+ // System.Diagnostics.Debug is thread-safe, so no need for lock(this).
+ System.Diagnostics.Debug.Flush();
+
+ return true;
+ }
+
#region Override implementation of AppenderSkeleton
/// <summary>
Added: logging/log4net/trunk/src/Appender/IFlushable.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/IFlushable.cs?rev=1765136&view=auto
==============================================================================
--- logging/log4net/trunk/src/Appender/IFlushable.cs (added)
+++ logging/log4net/trunk/src/Appender/IFlushable.cs Sun Oct 16 10:32:49 2016
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace log4net.Appender
+{
+ /// <summary>
+ /// Interface that can be implemented by Appenders that buffer logging data and expose a <see cref="Flush"/> method.
+ /// </summary>
+ public interface IFlushable
+ {
+ /// <summary>
+ /// Flushes any buffered log data.
+ /// </summary>
+ /// <remarks>
+ /// Appenders that implement the <see cref="Flush"/> method must do so in a thread-safe manner: it can be called concurrently with
+ /// the <see cref="log4net.Appender.IAppender.DoAppend"/> method.
+ /// <para>
+ /// Typically this is done by locking on the Appender instance, e.g.:
+ /// <code>
+ /// <![CDATA[
+ /// public bool Flush(int millisecondsTimeout)
+ /// {
+ /// lock(this)
+ /// {
+ /// // Flush buffered logging data
+ /// ...
+ /// }
+ /// }
+ /// ]]>
+ /// </code>
+ /// </para>
+ /// <para>
+ /// The <paramref name="millisecondsTimeout"/> parameter is only relevant for appenders that process logging events asynchronously,
+ /// such as <see cref="RemotingAppender"/>.
+ /// </para>
+ /// </remarks>
+ /// <param name="millisecondsTimeout">The maximum time to wait for logging events to be flushed.</param>
+ /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
+ bool Flush(int millisecondsTimeout);
+ }
+}
Propchange: logging/log4net/trunk/src/Appender/IFlushable.cs
------------------------------------------------------------------------------
svn:eol-style = native
Modified: logging/log4net/trunk/src/Appender/RemotingAppender.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/RemotingAppender.cs?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/Appender/RemotingAppender.cs (original)
+++ logging/log4net/trunk/src/Appender/RemotingAppender.cs Sun Oct 16 10:32:49 2016
@@ -218,6 +218,17 @@ namespace log4net.Appender
}
}
+ /// <summary>
+ /// Flushes any buffered log data.
+ /// </summary>
+ /// <param name="millisecondsTimeout">The maximum time to wait for logging events to be flushed.</param>
+ /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
+ public override bool Flush(int millisecondsTimeout)
+ {
+ base.Flush();
+ return m_workQueueEmptyEvent.WaitOne(millisecondsTimeout, false);
+ }
+
#endregion
/// <summary>
Modified: logging/log4net/trunk/src/Appender/TextWriterAppender.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/TextWriterAppender.cs?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/Appender/TextWriterAppender.cs (original)
+++ logging/log4net/trunk/src/Appender/TextWriterAppender.cs Sun Oct 16 10:32:49 2016
@@ -42,7 +42,7 @@ namespace log4net.Appender
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
/// <author>Douglas de la Torre</author>
- public class TextWriterAppender : AppenderSkeleton
+ public class TextWriterAppender : AppenderSkeleton, IFlushable
{
#region Public Instance Constructors
@@ -481,5 +481,24 @@ namespace log4net.Appender
private readonly static Type declaringType = typeof(TextWriterAppender);
#endregion Private Static Fields
+
+ /// <summary>
+ /// Flushes any buffered log data.
+ /// </summary>
+ /// <param name="millisecondsTimeout">The maximum time to wait for logging events to be flushed.</param>
+ /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
+ public bool Flush(int millisecondsTimeout)
+ {
+ // Nothing to do if ImmediateFlush is true
+ if (m_immediateFlush) return true;
+
+ // lock(this) will block any Appends while the buffer is flushed.
+ lock (this)
+ {
+ m_qtw.Flush();
+ }
+
+ return true;
+ }
}
}
Modified: logging/log4net/trunk/src/Appender/TraceAppender.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/TraceAppender.cs?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/Appender/TraceAppender.cs (original)
+++ logging/log4net/trunk/src/Appender/TraceAppender.cs Sun Oct 16 10:32:49 2016
@@ -51,7 +51,7 @@ namespace log4net.Appender
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
/// <author>Ron Grabowski</author>
- public class TraceAppender : AppenderSkeleton
+ public class TraceAppender : AppenderSkeleton, IFlushable
{
#region Public Instance Constructors
@@ -206,5 +206,24 @@ namespace log4net.Appender
private PatternLayout m_category = new PatternLayout("%logger");
#endregion Private Instance Fields
- }
+
+ /// <summary>
+ /// Flushes any buffered log data.
+ /// </summary>
+ /// <param name="millisecondsTimeout">The maximum time to wait for logging events to be flushed.</param>
+ /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
+ public bool Flush(int millisecondsTimeout)
+ {
+ // Nothing to do if ImmediateFlush is true
+ if (m_immediateFlush) return true;
+
+ // System.Diagnostics.Trace and System.Diagnostics.Debug are thread-safe, so no need for lock(this).
+#if NETCF
+ System.Diagnostics.Debug.Flush();
+#else
+ System.Diagnostics.Trace.Flush();
+#endif
+ return true;
+ }
+ }
}
Modified: logging/log4net/trunk/src/LogManager.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/LogManager.cs?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/LogManager.cs (original)
+++ logging/log4net/trunk/src/LogManager.cs Sun Oct 16 10:32:49 2016
@@ -751,6 +751,25 @@ namespace log4net
return LoggerManager.GetAllRepositories();
}
+ /// <summary>
+ /// Flushes logging events buffered in all configured appenders in the default repository.
+ /// </summary>
+ /// <param name="millisecondsTimeout">The maximum time in milliseconds to wait for logging events from asycnhronous appenders to be flushed,
+ /// or <see cref="Timeout.Infinite"/> to wait indefinitely.</param>
+ /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
+ public static bool Flush(int millisecondsTimeout)
+ {
+ Appender.IFlushable flushableRepository = LoggerManager.GetRepository(Assembly.GetCallingAssembly()) as Appender.IFlushable;
+ if (flushableRepository == null)
+ {
+ return false;
+ }
+ else
+ {
+ return flushableRepository.Flush(millisecondsTimeout);
+ }
+ }
+
#endregion Domain & Repository Manager Methods
#region Extension Handlers
Modified: logging/log4net/trunk/src/Repository/LoggerRepositorySkeleton.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Repository/LoggerRepositorySkeleton.cs?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/Repository/LoggerRepositorySkeleton.cs (original)
+++ logging/log4net/trunk/src/Repository/LoggerRepositorySkeleton.cs Sun Oct 16 10:32:49 2016
@@ -23,6 +23,7 @@ using log4net.ObjectRenderer;
using log4net.Core;
using log4net.Util;
using log4net.Plugin;
+using System.Threading;
namespace log4net.Repository
{
@@ -40,7 +41,7 @@ namespace log4net.Repository
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public abstract class LoggerRepositorySkeleton : ILoggerRepository
+ public abstract class LoggerRepositorySkeleton : ILoggerRepository, Appender.IFlushable
{
#region Member Variables
@@ -573,5 +574,59 @@ namespace log4net.Repository
{
OnConfigurationChanged(e);
}
+
+ private static int GetWaitTime(DateTime startTimeUtc, int millisecondsTimeout)
+ {
+ if (millisecondsTimeout == Timeout.Infinite) return Timeout.Infinite;
+ if (millisecondsTimeout == 0) return 0;
+
+ int elapsedMilliseconds = (int)(DateTime.UtcNow - startTimeUtc).TotalMilliseconds;
+ int timeout = millisecondsTimeout - elapsedMilliseconds;
+ if (timeout < 0) timeout = 0;
+ return timeout;
+ }
+
+ /// <summary>
+ /// Flushes all configured Appenders that implement <see cref="log4net.Appender.IFlushable"/>.
+ /// </summary>
+ /// <param name="millisecondsTimeout">The maximum time in milliseconds to wait for logging events from asycnhronous appenders to be flushed,
+ /// or <see cref="Timeout.Infinite"/> to wait indefinitely.</param>
+ /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
+ public bool Flush(int millisecondsTimeout)
+ {
+ if (millisecondsTimeout < -1) throw new ArgumentOutOfRangeException("millisecondsTimeout", "Timeout must be -1 (Timeout.Infinite) or non-negative");
+
+ // Assume success until one of the appenders fails
+ bool result = true;
+
+ // Use DateTime.UtcNow rather than a System.Diagnostics.Stopwatch for compatibility with .NET 1.x
+ DateTime startTimeUtc = DateTime.UtcNow;
+
+ // Do buffering appenders first. These may be forwarding to other appenders
+ foreach(var appender in GetAppenders())
+ {
+ log4net.Appender.IFlushable flushable = appender as log4net.Appender.IFlushable;
+ if (flushable == null) continue;
+ if (appender is Appender.BufferingAppenderSkeleton)
+ {
+ int timeout = GetWaitTime(startTimeUtc, millisecondsTimeout);
+ if (!flushable.Flush(timeout)) result = false;
+ }
+ }
+
+ // Do non-buffering appenders.
+ foreach (var appender in GetAppenders())
+ {
+ log4net.Appender.IFlushable flushable = appender as log4net.Appender.IFlushable;
+ if (flushable == null) continue;
+ if (!(appender is Appender.BufferingAppenderSkeleton))
+ {
+ int timeout = GetWaitTime(startTimeUtc, millisecondsTimeout);
+ if (!flushable.Flush(timeout)) result = false;
+ }
+ }
+
+ return result;
+ }
}
}
Modified: logging/log4net/trunk/src/log4net.vs2008.csproj
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/log4net.vs2008.csproj?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/log4net.vs2008.csproj (original)
+++ logging/log4net/trunk/src/log4net.vs2008.csproj Sun Oct 16 10:32:49 2016
@@ -148,6 +148,9 @@
<Compile Include="Appender\IBulkAppender.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Appender\IFlushable.cs">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="Appender\LocalSyslogAppender.cs">
<SubType>Code</SubType>
</Compile>
Modified: logging/log4net/trunk/src/log4net.vs2010.csproj
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/log4net.vs2010.csproj?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/log4net.vs2010.csproj (original)
+++ logging/log4net/trunk/src/log4net.vs2010.csproj Sun Oct 16 10:32:49 2016
@@ -166,6 +166,9 @@
<Compile Include="Appender\IBulkAppender.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Appender\IFlushable.cs">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="Appender\LocalSyslogAppender.cs">
<SubType>Code</SubType>
</Compile>
Modified: logging/log4net/trunk/src/log4net.vs2012.csproj
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/log4net.vs2012.csproj?rev=1765136&r1=1765135&r2=1765136&view=diff
==============================================================================
--- logging/log4net/trunk/src/log4net.vs2012.csproj (original)
+++ logging/log4net/trunk/src/log4net.vs2012.csproj Sun Oct 16 10:32:49 2016
@@ -166,6 +166,9 @@
<Compile Include="Appender\IBulkAppender.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Appender\IFlushable.cs">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="Appender\LocalSyslogAppender.cs">
<SubType>Code</SubType>
</Compile>