Asynchronous Logging in .NET Application

Topics: Exception Handling Application Block, Logging Application Block
Dec 2, 2014 at 5:49 AM
I am looking for information on Asynchronous logging using Enterprise Libraries 6
Want to know implemenatation details and challenges. Please share if anyone has implemented this

Key asks are:

1.Logging to be done asynchronously to files. - This can be done using Enterprise Libraries 6.0

AsynchronousTraceListenerWrapper Class
Logging Asynchronously section in
However, the risk with writing log messages asynchronously is that if the internal buffer overflows or the application shuts down before all the entries are flushed, you will lose some log messages. It is possible to adjust the size of the buffer to your requirements.
  1. Set Thread pool for logging and trigger a mail to support team after the thread pool is crossed??
Please share any relavent info
Dec 2, 2014 at 1:47 PM
As you mention Enterprise Library supports async logging. To log asynchronously is just a matter of setting the XML configuration to be async (or wrapping a trace listener in an AsynchronousTraceListenerWrapper if using programmatic configuration). Here is the relevant section of the Developers Guide:

If you download the reference documents there is some additional information:
You can use the asynchronous trace listener in the same way that you would use the wrapped listener in your code.

The AsynchronousTraceListenerWrapper constructor has three optional parameters in addition to the wrapped listener.

ownsWrappedListener. Indicates whether the wrapper should dispose the wrapped trace listener.
bufferSize. Size of the buffer for asynchronous requests.
maxDegreeOfParallelism. The maximum degree of parallelism for thread safe listeners.
disposeTimeout. The timeout for waiting to complete buffered requests when disposing. When null (the default) the timeout is infinite.
If the buffer overflows, you may lose some messages.
In terms of losing messages during application shutdown you can configure the disposeTimeout and ensure in your application that LogWriters are disposed during an orderly shutdown. However, there is no deterministic guarantee that all messages in the buffer will be written (e.g. power failure, crash, etc.).

Another scenario in which messages could be lost is if the buffer is full. Async logging is handled by a long running task and does not spawn a thread for each message so monitoring the thread pool is not useful.

However, if you configure the errors special source you should be able to capture that event along with the original information. The errors special source could use an email trace listener to send emails to support team (for all logging errors) Here is a (sanitized) example of what you would see:
Logging Errors & Warnings Error: 6352 : Timestamp: 12/2/2014 1:23:03 PM
Message: Tracing to LogSource 'General' failed. Processing for other sources will continue. See summary information below for more information. Should this problem persist, stop the service and check the configuration file(s) for possible error(s) in the configuration of the categories and sinks.

Summary for Enterprise Library Distributor Service:
Timestamp: 12/2/2014 1:23:03 PM
Message: Test
Category: General
Priority: -1
EventId: 1
Severity: Information
ProcessId: 7420
Thread Name: 
Win32 ThreadId:6780
Extended Properties: 
--> TimeStamp: 12/2/2014 1:23:03 PM
--> FullName: Microsoft.Practices.EnterpriseLibrary.Logging, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35

Exception Information Details:
Exception Type: System.InvalidOperationException
Message: The capacity for the asynchronous trace listener named '' is exhausted.
Data: System.Collections.ListDictionaryInternal
TargetSite: Void AddRequest(System.Action`1[System.Diagnostics.TraceListener])
HelpLink: NULL
Source: Microsoft.Practices.EnterpriseLibrary.Logging
HResult: -2146233079

StackTrace Information Details: 
   at Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.AsynchronousTraceListenerWrapper.AddRequest(Action`1 request)
   at Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.AsynchronousTraceListenerWrapper.TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, Int32 id, Object data, ReportTracingError reportError)
   at Microsoft.Practices.EnterpriseLibrary.Logging.LogSource.TraceData(TraceEventType eventType, Int32 id, LogEntry logEntry, TraceListenerFilter traceListenerFilter, TraceEventCache traceEventCache, ReportTracingError reportError)
Priority: -1
EventId: 6352
Severity: Error
ProcessId: 7420
Thread Name: 
Win32 ThreadId:6780
Extended Properties: 
If you require that a message is guaranteed to be logged (e.g. regulatory auditing) then a fire and forget approach is probably not the best.

Also If you are starting from scratch you may want to look at the Semantic Logging Application Block.

Randy Levy
Enterprise Library support engineer
Support How-to