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;