Last active
September 25, 2015 08:43
-
-
Save PolarbearDK/5f17e40721816edec8b8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Diagnostics; | |
using System.Runtime.InteropServices; | |
using System.Threading.Tasks; | |
using log4net; | |
namespace MyNamespace | |
{ | |
/// <summary> | |
/// Trace listner that writes Trace events to Log4Net | |
/// </summary> | |
/// <example> | |
/// Sample basic configuration: | |
/// <configuration> | |
/// <system.diagnostics> | |
/// <trace autoflush = "false" indentsize="4"> | |
/// <listeners> | |
/// <add name = "log4net" type="MyNamespace.Log4NetTraceListener, MyNamespace" /> | |
/// <remove name = "Default" /> | |
/// </listeners > | |
/// </trace > | |
/// </system.diagnostics > | |
/// </configuration > | |
/// </example> | |
public class Log4NetTraceListener : TraceListener | |
{ | |
private ILog _log; | |
// Hold messages while logging framework is starting up. | |
private ConcurrentQueue<string> _deferred; | |
public Log4NetTraceListener() | |
{ | |
_deferred = new ConcurrentQueue<string>(); | |
// Start async initialization of log4net | |
Task t = Task.Factory.StartNew(async () => | |
{ | |
// Initialize log4net | |
_log = LogManager.GetLogger(typeof(Log4NetTraceListener)); | |
var deferred = _deferred; | |
_deferred = null; | |
// Now wait for logging subsystem to come online | |
await Task.Delay(TimeSpan.FromSeconds(10)); | |
// Write any deferred messages. | |
if (!deferred.IsEmpty) | |
{ | |
string message; | |
_log.Debug("--- Deferred messages start ---"); | |
while (deferred.TryDequeue(out message)) | |
{ | |
_log.Debug(message); | |
} | |
_log.Debug("--- Deferred messages end ---"); | |
} | |
}); | |
} | |
public Log4NetTraceListener(ILog log) | |
{ | |
if (log == null) throw new ArgumentNullException(nameof(log)); | |
_log = log; | |
} | |
[ComVisible(false)] | |
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType eventType, int id, string message) | |
{ | |
TraceEvent(eventCache, source, eventType, id, message, null); | |
} | |
// All other TraceEvent methods come through this one. | |
[ComVisible(false)] | |
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType eventType, int id, string messageOrFormat, params object[] args) | |
{ | |
if (_log == null || (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, messageOrFormat, null, null, null))) | |
return; | |
var message = args != null | |
? string.Format(messageOrFormat, args) | |
: messageOrFormat; | |
// Minor hack. If first args argument is an Exception thn use it in log4net call. | |
Exception exception = null; | |
if (args != null && args.Length > 0) | |
{ | |
exception = args[0] as Exception; | |
} | |
switch (eventType) | |
{ | |
case TraceEventType.Critical: | |
if (exception != null) | |
_log.Fatal(message, exception); | |
else | |
_log.Fatal(message); | |
break; | |
case TraceEventType.Error: | |
if (exception != null) | |
_log.Error(message, exception); | |
else | |
_log.Error(message); | |
break; | |
case TraceEventType.Warning: | |
if (exception != null) | |
_log.Warn(message, exception); | |
else | |
_log.Warn(message); | |
break; | |
case TraceEventType.Information: | |
if (exception != null) | |
_log.Info(message, exception); | |
else | |
_log.Info(message); | |
break; | |
default: | |
if (exception != null) | |
_log.Debug(message, exception); | |
else | |
_log.Debug(message); | |
break; | |
} | |
} | |
public override void Write(string message) | |
{ | |
WriteLine(message); | |
} | |
public override void WriteLine(string message) | |
{ | |
if (_log != null) | |
{ | |
_log.Debug(message); | |
} | |
else | |
{ | |
var d = _deferred; | |
if (d != null) | |
{ | |
d.Enqueue(message); | |
} | |
else | |
{ | |
// Try one final time in case initialization just finished | |
if (_log != null) | |
{ | |
_log.Debug(message); | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment