- Notifications
You must be signed in to change notification settings - Fork1.4k
AsyncWrapper target
Enables asynchronous logging, so the application-thread will only have the overhead of NLog automatically capturing thread-context (Ex.${threadid}
) and pushing to a concurrent-queue. Background timer-event using Dotnet-ThreadPool for writing pending LogEvents from the concurrent-queue to the wrapped target. It also activates batch-writing of LogEvents for even better performance.
Platforms Supported:All
<targets> <targetxsi:type="AsyncWrapper"name="String"queueLimit="Integer"timeToSleepBetweenBatches="Integer"batchSize="Integer"overflowAction="Enum"> <targetxsi:type="wrappedTargetType" ...target properties... /> </target></targets>
- name - Name of the target.
queueLimit - Limit on the number of requests the background-writer thread can have in the queue. Integer Default:
10000
timeToSleepBetweenBatches - Time in milliseconds to sleep between batches. Integer Default:
1
(NLog 4.6 changed default from50
to1
). When set to '0' or '1', then it will only trigger timer when something is logged (Less timer activity when idle, Faster logging and improved garbage collection behavior).batchSize - Number of log events that should be processed in a batch by the background-writer thread. Integer Default: 100 (NLog 4.4.2 and newer has Default: 200)
fullBatchSizeWriteLimit - Max number of consecutive fullbatchSize writes to perform within the same timer event. Integer Default: 5. Introduced in NLog 4.4.2
overflowAction - Action to be taken when in-memory-queue becomes full (ReachedqueueLimit). This means the background-writer is falling behind, and cannot keep up with the application-threads logging. Default: Discard
Possible values:- Discard - The application-thread will discard logevent to avoid becoming blocked or causing out-of-memory issues. If memory and large-object-heap usage is not an issue, then one can consider increasingqueueLimit to 100.000. (Default)
- Block - The application-thread will block until the background-writer-thread has taken the next batch. Avoids loosing important logevents, but can block all application-threads. Consider to throttle active thread count, by limiting number of concurrent inbound requests.
- Grow - The application-thread will ignore the
queueLimit
, and will just allocate more memory. Can cause the entire application to experience out-of-memory-issues.
ForceLockingQueue - Force thread synchronization with monitor-lock, instead of using .NET ConcurrentQueue. Legacy NetFramework application will by default use monitor-lock (Default=true). .NET Standard 2.0 will by default use of the .NET lock-free ConcurrentQueue for improved concurrency (Default=false).
Introduced in NLog 4.6
Remember to Flush before application exit, is very important when enabling use of the Asynchronous target wrapper.
Asynchronous target wrapper allows the logger code to execute more quickly, by queuing messages for processing by background writer-thread. You should wrap targets that spend a non-trivial amount of time in theirWrite()
method with asynchronous target to speed up logging. Because asynchronous logging is quite a common scenario, NLog supports a shorthand notation for wrapping all targets with AsyncWrapper. Just addasync="true"
to the<targets/>
element in the configuration file.
Example:
<targetsasync="true"> ... your targets go here ...</targets>
The async attribute is a shorthand for:
xsi:type="AsyncWrapper overflowAction="Discard" queueLimit="10000" batchSize="200" timeToSleepBetweenBatches="1"
So if you write a lot of messages (more then 10000) in a short time, it's possible that messages will be lost. This is intended behavior as keeping all the messages or waiting for all the messages to be written, could have impact on the performance of your program.
If you need all the log messages, then you can change from<targets async="true">
to using<default-wrapper>
:
<targets> <default-wrapperxsi:type="AsyncWrapper"overflowAction="Block" /> ... your targets go here ...</targets>
When using theAsyncWrapper
, do write to the wrapper in your <rules>
section! In the following example: do write to"target2". If the<logger>
is writing to "target1", the messages are not written asynchronously!
<targets> <targetname="target2"xsi:type="AsyncWrapper"> <target name ="target1"xsi:type="File"fileName="c:/temp/test.log"layout="${message}"keepFileOpen="true" /> </target> <rules> <loggername="*"minlevel="Info"writeTo="target2"/> </rules> </targets>
When messages are written asynchronously, then writing is performed by the background-writer-thread. There can be custom NLog targets that requires writing to happen on the application-thread for proper context capture. When used together with AsyncWrapper then asynchronous writing is used and context information can be lost.
By default all standard NLog targets supports use of AsyncWrapper. Custom NLog targets that inherits fromTargetWithContext
should also by default work correctly with AsyncWrapper.
TheBufferingWrapper can also be asynchronously when having configuredFlushTimeout
. AsyncWrapper is intended for improving performance, where BufferingWrapper is intended for throttling or even discarding LogEvents. AsyncWrapper has an internal buffer optimized to handle many concurrent threads.
-Troubleshooting Guide - See available NLog Targets and Layouts:https://nlog-project.org/config
- All targets, layouts and layout renderers
Popular: - Using NLog with NLog.config
- Using NLog with appsettings.json