Created
May 30, 2015 03:23
-
-
Save IanYates/7f31abe19610ca653a3b to your computer and use it in GitHub Desktop.
System.Diagnostics.TraceListener to Windsor ILogger
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.Diagnostics; | |
using System.Globalization; | |
using Castle.Core.Logging; | |
namespace Dox.Server.Web.Utilities.Logging | |
{ | |
/// <summary> | |
/// TraceListener implementation that directs all output to Serilog via the Windsor ILogger | |
/// </summary> | |
public class TraceListenerToILogger: System.Diagnostics.TraceListener | |
{ | |
const LoggerLevel FailLevel = LoggerLevel.Fatal; | |
const LoggerLevel DefaultLogLevel = LoggerLevel.Debug; | |
const string MessagelessTraceEventMessageTemplate = "{TraceSource:l} {TraceEventType}: {TraceEventId}"; | |
const string MesageMessageTemplate = "{TraceMessage:l}"; | |
const string MessageWithCategoryMessageTemplate = "{Category:l}: {TraceMessage:l}"; | |
const string FailMessageTemplate = "Fail: {TraceMessage:l}"; | |
const string DetailedFailMessageTemplate = "Fail: {TraceMessage:l} {FailDetails:l}"; | |
static readonly string TraceDataMessageTemplate = "{TraceSource:l} {TraceEventType}: {TraceEventId} :" + Environment.NewLine + "{TraceData:l}"; | |
static readonly string TraceEventMessageTemplate = "{TraceSource:l} {TraceEventType}: {TraceEventId} :" + Environment.NewLine + "{TraceMessage:l}"; | |
static readonly string TraceTransferMessageTemplate = "{TraceSource:l} {TraceEventType}: {TraceEventId} :" + Environment.NewLine + "{TraceMessage:l}, relatedActivityId={RelatedActivityId}"; | |
ILogger logger; | |
/// <summary> | |
/// Creates a SerilogTraceListener that uses the logger from `Serilog.Log` | |
/// </summary> | |
/// <remarks> | |
/// This is needed because TraceListeners are often configured through XML | |
/// where there would be no opportunity for constructor injection | |
/// </remarks> | |
public TraceListenerToILogger() | |
: this("Unspecified", new WindsorSerilogLogger(Serilog.Log.Logger)) | |
{ | |
} | |
/// <summary> | |
/// Creates a SerilogTraceListener that uses the specified logger | |
/// </summary> | |
public TraceListenerToILogger(string logName, ILogger logger) | |
{ | |
this.logger = logger.ForContext("TraceListener", logName).UpliftTo(DefaultLogLevel); | |
} | |
public TraceListenerToILogger(string logName) | |
:this(logName, new WindsorSerilogLogger(Serilog.Log.Logger)) | |
{ | |
} | |
public override bool IsThreadSafe | |
{ | |
get { return true; } | |
} | |
public override void Write(string message) | |
{ | |
logger.DebugFormat(MesageMessageTemplate, message); | |
} | |
public override void Write(string message, string category) | |
{ | |
logger.DebugFormat(MessageWithCategoryMessageTemplate, category, message); | |
} | |
public override void WriteLine(string message) | |
{ | |
Write(message); | |
} | |
public override void WriteLine(string message, string category) | |
{ | |
Write(message, category); | |
} | |
public override void Fail(string message) | |
{ | |
logger.ErrorFormat(FailMessageTemplate, message); | |
} | |
public override void Fail(string message, string detailMessage) | |
{ | |
logger.ErrorFormat(DetailedFailMessageTemplate, message, detailMessage); | |
} | |
public override void Close() | |
{ | |
logger = new NullLogger(); | |
base.Close(); | |
} | |
public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data) | |
{ | |
WriteEvent(eventCache, eventType, TraceDataMessageTemplate, source, eventType, id, data); | |
} | |
public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data) | |
{ | |
WriteEvent(eventCache, eventType, TraceDataMessageTemplate, source, eventType, id, data); | |
} | |
public override void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId) | |
{ | |
WriteEvent(eventCache, TraceEventType.Transfer, TraceTransferMessageTemplate, source, TraceEventType.Transfer, id, message, relatedActivityId); | |
} | |
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id) | |
{ | |
WriteEvent(eventCache, eventType, MessagelessTraceEventMessageTemplate, source, eventType, id); | |
} | |
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) | |
{ | |
WriteEvent(eventCache, eventType, TraceEventMessageTemplate, source, eventType, id, message); | |
} | |
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) | |
{ | |
TraceEvent(eventCache, source, eventType, id, string.Format(CultureInfo.InvariantCulture, format, args ?? new object[0])); | |
} | |
void WriteEvent(TraceEventCache eventCache, TraceEventType eventType, string messageTemplate, params object[] propertyValues) | |
{ | |
LoggerLevel level = ToLogEventLevel(eventType); | |
logger | |
.UpliftTo(level) //lets us use .Debug and then still get the desired level of output | |
.DebugFormat(messageTemplate, propertyValues ?? new object[0]); | |
} | |
internal static LoggerLevel ToLogEventLevel(TraceEventType eventType) | |
{ | |
switch (eventType) | |
{ | |
case TraceEventType.Critical: | |
{ | |
return LoggerLevel.Fatal; | |
} | |
case TraceEventType.Error: | |
{ | |
return LoggerLevel.Error; | |
} | |
case TraceEventType.Information: | |
{ | |
return LoggerLevel.Info; | |
} | |
case TraceEventType.Warning: | |
{ | |
return LoggerLevel.Warn; | |
} | |
case TraceEventType.Verbose: | |
{ | |
return LoggerLevel.Debug; | |
} | |
default: | |
{ | |
return LoggerLevel.Debug; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment