Skip to content

Instantly share code, notes, and snippets.

@PolarbearDK
Last active September 25, 2015 08:43
Show Gist options
  • Save PolarbearDK/5f17e40721816edec8b8 to your computer and use it in GitHub Desktop.
Save PolarbearDK/5f17e40721816edec8b8 to your computer and use it in GitHub Desktop.
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