diff --git a/src/log4net/Appender/FileAppender.cs b/src/log4net/Appender/FileAppender.cs
index dbade37f..8853a8cc 100644
--- a/src/log4net/Appender/FileAppender.cs
+++ b/src/log4net/Appender/FileAppender.cs
@@ -160,7 +160,7 @@ public LockStateException(string message, Exception innerException) : base(messa
}
#if !NETCR && !NETSTANDARD1_3
- private LockStateException(SerializationInfo info, StreamingContext context) : base(info, context)
+ private LockStateException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
#endif
@@ -494,6 +494,7 @@ public FileAppender CurrentAppender
///
protected Stream CreateStream(string filename, bool append, FileShare fileShare)
{
+ filename = Environment.ExpandEnvironmentVariables(filename);
using (CurrentAppender.SecurityContext.Impersonate(this))
{
// Ensure that the directory structure exists
@@ -896,6 +897,118 @@ public override void OnClose()
}
#endif
+ ///
+ /// Hold no lock on the output file
+ ///
+ ///
+ ///
+ /// Open the file once and hold it open until is called.
+ /// Maintains no lock on the file during this time.
+ ///
+ ///
+ public class NoLock : LockingModelBase
+ {
+ private Stream m_stream = null;
+
+ ///
+ /// Open the file specified and prepare for logging.
+ ///
+ /// The filename to use
+ /// Whether to append to the file, or overwrite
+ /// The encoding to use
+ ///
+ ///
+ /// Open the file specified and prepare for logging.
+ /// No writes will be made until is called.
+ /// Must be called before any calls to ,
+ /// and .
+ ///
+ ///
+ public override void OpenFile(string filename, bool append, Encoding encoding)
+ {
+ try
+ {
+ // no lock
+ m_stream = CreateStream(filename, append, FileShare.ReadWrite);
+ }
+ catch (Exception e1)
+ {
+ CurrentAppender.ErrorHandler.Error("Unable to acquire lock on file " + filename + ". " + e1.Message);
+ }
+ }
+
+ ///
+ /// Close the file
+ ///
+ ///
+ ///
+ /// Close the file. No further writes will be made.
+ ///
+ ///
+ public override void CloseFile()
+ {
+ CloseStream(m_stream);
+ m_stream = null;
+ }
+
+ ///
+ /// Acquire the lock on the file
+ ///
+ /// A stream that is ready to be written to.
+ ///
+ ///
+ /// Does nothing. The lock is already taken
+ ///
+ ///
+ public override Stream AcquireLock()
+ {
+ return m_stream;
+ }
+
+ ///
+ /// Release the lock on the file
+ ///
+ ///
+ ///
+ /// Does nothing. The lock will be released when the file is closed.
+ ///
+ ///
+ public override void ReleaseLock()
+ {
+ // NOP
+ }
+
+ ///
+ /// Initializes all resources used by this locking model.
+ ///
+ public override void ActivateOptions()
+ {
+ // NOP
+ }
+
+ ///
+ /// Disposes all resources that were initialized by this locking model.
+ ///
+ public override void OnClose()
+ {
+ // NOP
+ }
+ }
+
+ ///
+ /// Default locking model (when no locking model was configured)
+ ///
+ private static Type defaultLockingModelType = typeof(ExclusiveLock);
+
+ ///
+ /// Specify default locking model
+ ///
+ /// Type of LockingModel
+ public static void SetDefaultLockingModelType() where TLockingModel : LockingModelBase
+ {
+ defaultLockingModelType = typeof(TLockingModel);
+ }
+
#endregion Locking Models
#region Public Instance Constructors
@@ -1112,7 +1225,7 @@ public override void ActivateOptions()
if (m_lockingModel == null)
{
- m_lockingModel = new FileAppender.ExclusiveLock();
+ m_lockingModel = (LockingModelBase)Activator.CreateInstance(defaultLockingModelType);
}
m_lockingModel.CurrentAppender = this;