修复的问题汇总
Fix issue #804: Logging to same file from multiple processes misses messages
FileAppenders
MutexMultiProcessFileAppender.cs
RetryingMultiProcessFileAppender.cs
UnixMultiProcessFileAppender.cs
WindowsMultiProcessFileAppender.cs
Multi processes writing same file
The file target supports that multiple applications are concurrently writing to the same file. This mode is activated with concurrentWrites=true
. The IIS-application can run multiple AppDomains, and each AppDomain operates like a child process. When multiple processes are concurrently writing to the same file, then some locking for coordination is needed. NLog has support for the following locking-modes:
-
Operating System File Locks - Default mode that is supported on most platforms. This mode is enabled with
KeepFileOpen=False
. File locking from operating system are not fair and doesn't scale when having more than 2 processes writing to the same file. Exceptions will be thrown when one process tries to open a file, that is currently in use by another process. NLog tries to handle these exception by retrying on error (concurrentWriteAttempts=10
) together with randomizing how long to wait before retry (concurrentWriteAttemptDelay=1
). When you start to increase the number of processes, then the chance of failing 10 times in row increases, and so log messages are lost. -
Global Mutex Locks - NLog can use global mutex for inter-process communication, which is supported on many platforms. This mode is enabled with
KeepFileOpen=True
andConcurrentWrites=true
. The performance is better than file locks and with much less memory allocations. It works great on Windows, and most Linux platforms using NetCore2 or newer versions of MONO. But seldom很少 works for platforms for mobile devices like UWP / Xamarin Android / Xamarin iOS as these platforms runs in restricted sandbox without access to global mutex. -
Atomic File Append - .NET Framework on Windows has support for atomic file append mode. This mode is enabled with
KeepFileOpen=True
andConcurrentWrites=true
. This mode is only supported for .NET Framework on Windows platform. The lock synchronization is fair, and happens at the operating system level. It is the fastest concurrent mode available with minimum overhead.
It is recommended to enable asynchronous logging as it will reduce the overhead from file locking coordination.
Batch write and asynchronous logging
The file target has support for batch writing, where multiple log messages are written in one file-operation. Batch write will improve performance, especially when using KeepFileOpen=false
. Batch writing is enabled automatically when using the AsyncWrapper. This can be done by adding the attribute async="true"
to the <targets>
-element.
Asynchronous logging is recommended for multi-threaded server applications, but might not be worth it for quick-finishing command line application. Make sure to remember to flush at application shutdown, or else output can be dropped.
<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets async="true">
<target type="File" name="logfile" fileName="${basedir}/logs/${level}.txt" keepFileOpen="true" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>