From ddeafdb9dd76e404e9401b4fd3c97584a0501ecd Mon Sep 17 00:00:00 2001 From: tmont Date: Sat, 11 Apr 2009 20:53:14 +0000 Subject: [PATCH] SimpleLog: added message handler, made a bunch of enhancements --- SimpleLog/DefaultMessageHandler.cs | 100 ++++++++++++++++++++++++ SimpleLog/ILogHandler.cs | 4 +- SimpleLog/ILogger.cs | 15 ++++ SimpleLog/IMessageFormatter.cs | 10 +++ SimpleLog/IMessageHandler.cs | 11 +++ SimpleLog/Logger.cs | 118 +++++++++++++++++++++-------- SimpleLog/MessageHandler.cs | 12 --- SimpleLog/SimpleLog.csproj | 4 + SimpleLog/Util.cs | 20 +++++ 9 files changed, 247 insertions(+), 47 deletions(-) create mode 100644 SimpleLog/DefaultMessageHandler.cs create mode 100644 SimpleLog/ILogger.cs create mode 100644 SimpleLog/IMessageFormatter.cs create mode 100644 SimpleLog/IMessageHandler.cs delete mode 100644 SimpleLog/MessageHandler.cs create mode 100644 SimpleLog/Util.cs diff --git a/SimpleLog/DefaultMessageHandler.cs b/SimpleLog/DefaultMessageHandler.cs new file mode 100644 index 0000000..3d33df2 --- /dev/null +++ b/SimpleLog/DefaultMessageHandler.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SimpleLog { + public class DefaultMessageHandler : IMessageHandler, IMessageFormatter { + + protected string dateFormat; + protected string lineTerminator; + protected string context; + protected string delimiter; + + public DefaultMessageHandler() { + this.dateFormat = null; + this.lineTerminator = null; + this.context = ""; + this.delimiter = "\t"; + } + + #region IMessageHandler Members + public string ConstructLogMessage(ILogHandler handler, string message, LogLevel level) { + List messageData = new List(); + messageData.Add(string.Format("{0:" + this.DateFormat + "}", DateTime.Now)); + messageData.Add(level.ToString().ToUpper()); + if (!string.IsNullOrEmpty(this.Context)) { + messageData.Add(this.Context); + } + messageData.Add(message); + + return string.Join(this.Delimiter, messageData.ToArray()); + } + + /// + /// Converts the message object to a string. If the message object + /// is an exception, the new message is a concatenation of the Message + /// and StackTrace. Otherwise, the object's ToString() method is used for + /// conversion. + /// + /// The message object to convert + /// The message as a string + public string ConvertMessageToString(object message) { + string msg = null; + if (message is Exception) { + Exception e = (Exception)message; + msg = e.Message + "\n" + e.StackTrace; + } + else { + msg = message.ToString(); + } + return msg; + } + + /// + /// Gets or sets the context of this message handler + /// + public string Context { + get { + return this.context; + } + set { + this.context = value; + } + } + #endregion + + public string Delimiter { + get { + return this.delimiter; + } + set { + this.delimiter = value; + } + } + + #region IMessageFormatter members + public string DateFormat { + get { + return this.dateFormat; + } + set { + this.dateFormat = value; + } + } + public string LineTerminator { + get { + return this.lineTerminator; + } + set { + if (!Util.LineTerminatorIsValid(value)) { + throw new ArgumentException("Invalid line terminator; see SimpleLog.LineTerminator for valid line terminators"); + } + + this.lineTerminator = value; + } + } + #endregion + + } +} diff --git a/SimpleLog/ILogHandler.cs b/SimpleLog/ILogHandler.cs index 4bc389d..77ddaef 100644 --- a/SimpleLog/ILogHandler.cs +++ b/SimpleLog/ILogHandler.cs @@ -7,9 +7,9 @@ namespace SimpleLog { public interface ILogHandler { bool Log(object message, LogLevel level); - string Context { get; set; } LogLevel? LogLevel { get; set; } - string DateFormat { get; set; } + IMessageHandler MessageHandler { get; set; } + void GracefulShutDown(); } } diff --git a/SimpleLog/ILogger.cs b/SimpleLog/ILogger.cs new file mode 100644 index 0000000..512d41f --- /dev/null +++ b/SimpleLog/ILogger.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SimpleLog { + public interface ILogger : IMessageFormatter { + + bool Log(object message, LogLevel level); + void RegisterLogHandler(ILogHandler handler); + bool UnregisterLogHandler(ILogHandler handler); + int UnregisterLogHandlerType(string assemblyName); + + } +} diff --git a/SimpleLog/IMessageFormatter.cs b/SimpleLog/IMessageFormatter.cs new file mode 100644 index 0000000..338d201 --- /dev/null +++ b/SimpleLog/IMessageFormatter.cs @@ -0,0 +1,10 @@ +using System; + +namespace SimpleLog { + public interface IMessageFormatter { + + string DateFormat { get; set; } + string LineTerminator { get; set; } + + } +} diff --git a/SimpleLog/IMessageHandler.cs b/SimpleLog/IMessageHandler.cs new file mode 100644 index 0000000..5e73317 --- /dev/null +++ b/SimpleLog/IMessageHandler.cs @@ -0,0 +1,11 @@ +using System; + +namespace SimpleLog { + public interface IMessageHandler : IMessageFormatter { + + string ConstructLogMessage(ILogHandler handler, string message, LogLevel level); + string ConvertMessageToString(object message); + string Context { get; set; } + + } +} diff --git a/SimpleLog/Logger.cs b/SimpleLog/Logger.cs index 657228f..18c8d34 100644 --- a/SimpleLog/Logger.cs +++ b/SimpleLog/Logger.cs @@ -15,28 +15,48 @@ namespace SimpleLog { } public struct LineTerminator { + /// + /// Windows line terminator (CRLF) + /// public static readonly string Windows = "\r\n"; + /// + /// Macintosh line terminator (CR) + /// public static readonly string Mac = "\r"; + /// + /// Unix line terminator (LF) + /// public static readonly string Unix = "\n"; } - public class Logger { + public class Logger : ILogger { + /// + /// The singleton instance of this logger. All interactions + /// with the logger should be done via this static property. + /// public static readonly Logger Instance = new Logger(); + /// + /// Gets or sets whether this logger is enabled or not + /// + public bool Enabled; + protected List LogHandlers; + protected IMessageHandler messageHandler; protected LogLevel logLevel; protected string dateFormat; protected string lineTerminator; - public bool Enabled; private Logger() { this.LogHandlers = new List(); this.logLevel = LogLevel.Warning; - this.dateFormat = "YYYY-MM-dd HH:ii:ss"; - this.lineTerminator = LineTerminator.Unix; + this.lineTerminator = SimpleLog.LineTerminator.Unix; this.Enabled = true; + this.messageHandler = new DefaultMessageHandler(); + this.dateFormat = "YYYY-MM-dd HH:ii:ss"; } + #region ILogger members /// /// Logs a message at the specified log level /// @@ -47,12 +67,15 @@ namespace SimpleLog { bool success = true; if (this.Enabled) { - string convertedMessage = this.ConvertMessageToString(message); - + string convertedMessage; + LogLevel allowedLevel; + IMessageHandler messageHandler; foreach (ILogHandler handler in this.LogHandlers) { - LogLevel allowedLevel = handler.LogLevel ?? this.GlobalLogLevel; + allowedLevel = handler.LogLevel ?? this.LogLevel; if (level <= allowedLevel) { - convertedMessage = this.ConstructLogMessage(handler, convertedMessage); + messageHandler = handler.MessageHandler ?? this.MessageHandler; + convertedMessage = messageHandler.ConvertMessageToString(message); + convertedMessage = messageHandler.ConstructLogMessage(handler, convertedMessage, level); success = (success && handler.Log(convertedMessage, allowedLevel)); } } @@ -60,34 +83,61 @@ namespace SimpleLog { return success; } - - protected string ConvertMessageToString(object message) { - string msg = null; - if (message is Exception) { - Exception e = (Exception)message; - msg = e.Message + "\n" + e.StackTrace; - } - else { - msg = message.ToString(); - } - return msg; - } - protected virtual string ConstructLogMessage(ILogHandler handler, string message) { - string dateFormat = handler.DateFormat ?? this.GlobalDateFormat; - string timestamp = string.Format("{0:" + dateFormat + "}", DateTime.Now); - return timestamp; - } - + /// + /// Registers a log handler with this logger + /// + /// The log handler to register public void RegisterLogHandler(ILogHandler handler) { this.LogHandlers.Add(handler); } + /// + /// Unregisters the given log handler + /// + /// TRUE if successfully unregistered, FALSE if not + public bool UnregisterLogHandler(ILogHandler handler) { + if (this.LogHandlers.Contains(handler)) { + this.LogHandlers.Remove(handler); + handler.GracefulShutDown(); + return true; + } + + return false; + } + + /// + /// Removes all log handlers that match the given assembly name + /// + /// Number of log handlers that were unregistered + public int UnregisterLogHandlerType(string assemblyName) { + int count = 0; + foreach (ILogHandler handler in this.LogHandlers) { + if (handler.GetType().AssemblyQualifiedName == assemblyName) { + count += this.UnregisterLogHandler(handler) ? 1 : 0; + } + } + + return count; + } + #endregion + #region Accessors /// + /// Gets or sets the global message handler + /// + public IMessageHandler MessageHandler { + get { + return this.messageHandler; + } + set { + this.messageHandler = value; + } + } + /// /// Gets or sets the global log level /// - public LogLevel GlobalLogLevel { + public LogLevel LogLevel { get { return this.logLevel; } @@ -95,10 +145,13 @@ namespace SimpleLog { this.logLevel = value; } } + #endregion + + #region IMessageFormatter members /// /// Gets or sets the global date format /// - public string GlobalDateFormat { + public string DateFormat { get { return this.dateFormat; } @@ -109,17 +162,16 @@ namespace SimpleLog { /// /// Gets or sets the global line terminator /// - public string GlobalLineTerminator { + public string LineTerminator { get { return this.lineTerminator; } set { - if (value == LineTerminator.Unix || value == LineTerminator.Windows || value == LineTerminator.Mac) { - this.lineTerminator = value; - } - else { + if (!Util.LineTerminatorIsValid(value)) { throw new ArgumentException("Invalid line terminator; see SimpleLog.LineTerminator struct for valid line terminators"); } + + this.lineTerminator = value; } } #endregion diff --git a/SimpleLog/MessageHandler.cs b/SimpleLog/MessageHandler.cs deleted file mode 100644 index 37e7abc..0000000 --- a/SimpleLog/MessageHandler.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace SimpleLog { - public class MessageHandler { - - - - } -} diff --git a/SimpleLog/SimpleLog.csproj b/SimpleLog/SimpleLog.csproj index d467328..e6983b1 100644 --- a/SimpleLog/SimpleLog.csproj +++ b/SimpleLog/SimpleLog.csproj @@ -45,10 +45,14 @@ + + + +