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 2011/09/20 13:13:47 UTC

svn commit: r1173083 - in /logging/log4net/trunk: src/Appender/FileAppender.cs src/site/xdoc/release/config-examples.xml src/site/xdoc/release/faq.xml tests/src/Appender/RollingFileAppenderTest.cs

Author: bodewig
Date: Tue Sep 20 11:13:46 2011
New Revision: 1173083

URL: http://svn.apache.org/viewvc?rev=1173083&view=rev
Log:
MutexLock => InterProcessLock.  Document it, discourage its use.  LOG4NET-164

Modified:
    logging/log4net/trunk/src/Appender/FileAppender.cs
    logging/log4net/trunk/src/site/xdoc/release/config-examples.xml
    logging/log4net/trunk/src/site/xdoc/release/faq.xml
    logging/log4net/trunk/tests/src/Appender/RollingFileAppenderTest.cs

Modified: logging/log4net/trunk/src/Appender/FileAppender.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/FileAppender.cs?rev=1173083&r1=1173082&r2=1173083&view=diff
==============================================================================
--- logging/log4net/trunk/src/Appender/FileAppender.cs (original)
+++ logging/log4net/trunk/src/Appender/FileAppender.cs Tue Sep 20 11:13:46 2011
@@ -61,9 +61,14 @@ namespace log4net.Appender
 	/// the <see cref="LockingModel"/> property.
 	/// The default behavior, implemented by <see cref="FileAppender.ExclusiveLock"/> 
 	/// is to obtain an exclusive write lock on the file until this appender is closed.
-	/// The alternative model, <see cref="FileAppender.MinimalLock"/>, only holds a
-	/// write lock while the appender is writing a logging event.
+	/// The alternative models, only hold a
+    /// write lock while the appender is writing a logging event (<see cref="FileAppender.MinimalLock"/>)
+    /// or synchronize by using a named system wide Mutex (<see cref="FileAppender.InterProcessLock"/>).
 	/// </para>
+    /// <para>
+    /// All locking strategies have issues and you should seriously consider using a different strategy that
+    /// avoids having multiple processes logging to the same file.
+    /// </para>
 	/// </remarks>
 	/// <author>Nicko Cadell</author>
 	/// <author>Gert Driesen</author>
@@ -589,7 +594,7 @@ namespace log4net.Appender
         /// </summary>
         /// <author>Ron Grabowski</author>
         /// <author>Steve Wranovsky</author>
-        public class MutexLock : LockingModelBase
+        public class InterProcessLock : LockingModelBase
         {
             private Mutex m_mutex = null;
             private bool m_mutexClosed = false;
@@ -832,9 +837,10 @@ namespace log4net.Appender
 		/// Gets or sets the <see cref="FileAppender.LockingModel"/> used to handle locking of the file.
 		/// </para>
 		/// <para>
-		/// There are two built in locking models, <see cref="FileAppender.ExclusiveLock"/> and <see cref="FileAppender.MinimalLock"/>.
-		/// The former locks the file from the start of logging to the end and the 
-		/// later lock only for the minimal amount of time when logging each message.
+        /// There are three built in locking models, <see cref="FileAppender.ExclusiveLock"/>, <see cref="FileAppender.MinimalLock"/> and <see cref="FileAppender.InterProcessLock"/> .
+		/// The first locks the file from the start of logging to the end, the 
+		/// second locks only for the minimal amount of time when logging each message
+        /// and the last synchronizes processes using a named system wide Mutex.
 		/// </para>
 		/// <para>
 		/// The default locking model is the <see cref="FileAppender.ExclusiveLock"/>.

Modified: logging/log4net/trunk/src/site/xdoc/release/config-examples.xml
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/site/xdoc/release/config-examples.xml?rev=1173083&r1=1173082&r2=1173083&view=diff
==============================================================================
--- logging/log4net/trunk/src/site/xdoc/release/config-examples.xml (original)
+++ logging/log4net/trunk/src/site/xdoc/release/config-examples.xml Tue Sep 20 11:13:46 2011
@@ -651,6 +651,25 @@ CREATE TABLE Log (
     </layout>
 </appender>
                 ]]></source>
+                <p>
+                    This example shows how to configure the appender to use the "inter process" locking
+                    model.
+                </p>
+                <source language="xml"><![CDATA[
+<appender name="FileAppender" type="log4net.Appender.FileAppender">
+    <file value="${TMP}\log-file.txt" />
+    <appendToFile value="true" />
+    <lockingModel type="log4net.Appender.FileAppender+InterProcessLock" />
+    <layout type="log4net.Layout.PatternLayout">
+        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
+    </layout>
+</appender>
+                ]]></source>
+                <p>
+                    Before you change the locking model so that
+                    multiple process may log to the same file, please
+                    read the <a href="faq.html#single-file">FAQ</a>.
+                </p>
             </section>
             
             <section id="forwardingappender" name="ForwardingAppender">

Modified: logging/log4net/trunk/src/site/xdoc/release/faq.xml
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/site/xdoc/release/faq.xml?rev=1173083&r1=1173082&r2=1173083&view=diff
==============================================================================
--- logging/log4net/trunk/src/site/xdoc/release/faq.xml (original)
+++ logging/log4net/trunk/src/site/xdoc/release/faq.xml Tue Sep 20 11:13:46 2011
@@ -657,24 +657,64 @@ public class FastLogger
 
 
                 <section id="single-file" name="How do I get multiple process to log to the same file?">
+                  <p>
+                    Before you even start trying any of the
+                    alternatives provided, ask yourself whether you
+                    really need to have multiple processes log to the
+                    same file, then don't do it ;-).
+                  </p>
+
+                  <p>
+                    FileAppender offers pluggable locking models for
+                    this usecase but all existing implementations have
+                    issues and drawbacks.
+                  </p>
+
+                    <p>
+                        By default the <span
+                        class="code">FileAppender</span> holds an
+                        exclusive write lock on the log file while it
+                        is logging. This prevents other processes from
+                        writing to the file.  This model is known to
+                        break down with (at least on some versions of)
+                        Mono on Linux and log files may get corrupted
+                        as soon as another process tries to access the
+                        log file.
+                    </p>
+
                     <p>
-                        By default the <span class="code">FileAppender</span> holds an exclusive write 
-                        lock on the log file while it is logging. This prevents other processes from 
-                        writing to the file. The <span class="code">FileAppender</span> can be configured
-                        to use a different locking model, <span class="code">MinimalLock</span>, that
-                        only acquires the write lock while a log is being written. This allows multiple
-                        processes to interleave writes to the same file, albeit with a loss in performance.
-                        See the <a href="config-examples.html#fileappender">FileAppender config examples</a>
-                        for an example <span class="code">MinimalLock</span> configuration.
-                    </p>
-                    <p>
-                        While the <span class="code">MinimalLock</span> model may be used to interleave
-                        writes to a single file it may not be the optimal solution, especially when
-                        logging from multiple machines. Alternatively you may have one or more processes
-                        log to <span class="code">RemotingAppenders</span>. 
-                        Using the <span class="code">RemoteLoggingServerPlugin</span> (or 
-                        <span class="code">IRemoteLoggingSink</span>) a process can receive all the events and 
-                        log them to a single log file.
+                      <span class="code">MinimalLock</span> only
+                      acquires the write lock while a log is being
+                      written. This allows multiple processes to
+                      interleave writes to the same file, albeit with
+                      a considerable loss in performance.
+                    </p>
+                    <p>
+                      <span class="code">InterProcessLock</span>
+                      doesn't lock the file at all but synchronizes
+                      using a system wide Mutex.  This will only work
+                      if all processes cooperate (and use the same
+                      locking model) and has also be paid for by a
+                      loss in performance.
+                    </p>
+                    <p>
+                      If you use <span
+                      class="code">RollingFileAppender</span> things
+                      become even worse as several process may try to
+                      start rolling the log file concurrently.
+                    </p>
+                    <p>
+                        A better alternative is to have your processes
+                        log to <span
+                        class="code">RemotingAppenders</span>.  Using
+                        the <span
+                        class="code">RemoteLoggingServerPlugin</span>
+                        (or <span
+                        class="code">IRemoteLoggingSink</span>) a
+                        process can receive all the events and log
+                        them to a single log file.  One of the
+                        examples shows how to use the <span
+                        class="code">RemoteLoggingServerPlugin</span>.
                     </p>
                 </section>
                 <p><a href="#top">Back to Top</a></p>

Modified: logging/log4net/trunk/tests/src/Appender/RollingFileAppenderTest.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/tests/src/Appender/RollingFileAppenderTest.cs?rev=1173083&r1=1173082&r2=1173083&view=diff
==============================================================================
--- logging/log4net/trunk/tests/src/Appender/RollingFileAppenderTest.cs (original)
+++ logging/log4net/trunk/tests/src/Appender/RollingFileAppenderTest.cs Tue Sep 20 11:13:46 2011
@@ -1582,7 +1582,7 @@ namespace log4net.Tests.Appender
 		}
 
 		/// <summary>
-		/// Verifies that attempting to log to a file with ExclusiveLock really locks the file
+		/// Verifies that attempting to log to a file with MinimalLock doesn't lock the file
 		/// </summary>
 		[Test]
 		public void TestMinimalLockUnlocks()
@@ -1612,14 +1612,14 @@ namespace log4net.Tests.Appender
         /// Verifies that attempting to log to a locked file fails gracefully
         /// </summary>
         [Test]
-        public void TestMutexLockFails() {
+        public void TestInterProcessLockFails() {
             String filename = "test.log";
 
             FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
             fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);
 
             SilentErrorHandler sh = new SilentErrorHandler();
-            ILogger log = CreateLogger(filename, new FileAppender.MutexLock(), sh);
+            ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh);
             log.Log(GetType(), Level.Info, "This is a message", null);
             log.Log(GetType(), Level.Info, "This is a message 2", null);
             DestroyLogger();
@@ -1633,14 +1633,14 @@ namespace log4net.Tests.Appender
         /// Verifies that attempting to log to a locked file recovers if the lock is released
         /// </summary>
         [Test]
-        public void TestMutexLockRecovers() {
+        public void TestInterProcessLockRecovers() {
             String filename = "test.log";
 
             FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
             fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);
 
             SilentErrorHandler sh = new SilentErrorHandler();
-            ILogger log = CreateLogger(filename, new FileAppender.MutexLock(), sh);
+            ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh);
             log.Log(GetType(), Level.Info, "This is a message", null);
             fs.Close();
             log.Log(GetType(), Level.Info, "This is a message 2", null);
@@ -1651,15 +1651,15 @@ namespace log4net.Tests.Appender
         }
 
         /// <summary>
-        /// Verifies that attempting to log to a file with ExclusiveLock really locks the file
+        /// Verifies that attempting to log to a file with InterProcessLock really locks the file
         /// </summary>
         [Test]
-        public void TestMutexLockUnlocks() {
+        public void TestInterProcessLockUnlocks() {
             String filename = "test.log";
             bool locked;
 
             SilentErrorHandler sh = new SilentErrorHandler();
-            ILogger log = CreateLogger(filename, new FileAppender.MutexLock(), sh);
+            ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh);
             log.Log(GetType(), Level.Info, "This is a message", null);
 
             locked = true;