SimpleLog: added message handler, made a bunch of enhancements
This commit is contained in:
parent
9cec382640
commit
ddeafdb9dd
100
SimpleLog/DefaultMessageHandler.cs
Normal file
100
SimpleLog/DefaultMessageHandler.cs
Normal file
@ -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<string> messageData = new List<string>();
|
||||
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());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="message">The message object to convert</param>
|
||||
/// <returns>The message as a string</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the context of this message handler
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
15
SimpleLog/ILogger.cs
Normal file
15
SimpleLog/ILogger.cs
Normal file
@ -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);
|
||||
|
||||
}
|
||||
}
|
10
SimpleLog/IMessageFormatter.cs
Normal file
10
SimpleLog/IMessageFormatter.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace SimpleLog {
|
||||
public interface IMessageFormatter {
|
||||
|
||||
string DateFormat { get; set; }
|
||||
string LineTerminator { get; set; }
|
||||
|
||||
}
|
||||
}
|
11
SimpleLog/IMessageHandler.cs
Normal file
11
SimpleLog/IMessageHandler.cs
Normal file
@ -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; }
|
||||
|
||||
}
|
||||
}
|
@ -15,28 +15,48 @@ namespace SimpleLog {
|
||||
}
|
||||
|
||||
public struct LineTerminator {
|
||||
/// <summary>
|
||||
/// Windows line terminator (CRLF)
|
||||
/// </summary>
|
||||
public static readonly string Windows = "\r\n";
|
||||
/// <summary>
|
||||
/// Macintosh line terminator (CR)
|
||||
/// </summary>
|
||||
public static readonly string Mac = "\r";
|
||||
/// <summary>
|
||||
/// Unix line terminator (LF)
|
||||
/// </summary>
|
||||
public static readonly string Unix = "\n";
|
||||
}
|
||||
|
||||
public class Logger {
|
||||
public class Logger : ILogger {
|
||||
|
||||
/// <summary>
|
||||
/// The singleton instance of this logger. All interactions
|
||||
/// with the logger should be done via this static property.
|
||||
/// </summary>
|
||||
public static readonly Logger Instance = new Logger();
|
||||
/// <summary>
|
||||
/// Gets or sets whether this logger is enabled or not
|
||||
/// </summary>
|
||||
public bool Enabled;
|
||||
|
||||
protected List<ILogHandler> LogHandlers;
|
||||
protected IMessageHandler messageHandler;
|
||||
protected LogLevel logLevel;
|
||||
protected string dateFormat;
|
||||
protected string lineTerminator;
|
||||
public bool Enabled;
|
||||
|
||||
private Logger() {
|
||||
this.LogHandlers = new List<ILogHandler>();
|
||||
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
|
||||
/// <summary>
|
||||
/// Logs a message at the specified log level
|
||||
/// </summary>
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
@ -61,33 +84,60 @@ 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a log handler with this logger
|
||||
/// </summary>
|
||||
/// <param name="handler">The log handler to register</param>
|
||||
public void RegisterLogHandler(ILogHandler handler) {
|
||||
this.LogHandlers.Add(handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters the given log handler
|
||||
/// </summary>
|
||||
/// <returns>TRUE if successfully unregistered, FALSE if not</returns>
|
||||
public bool UnregisterLogHandler(ILogHandler handler) {
|
||||
if (this.LogHandlers.Contains(handler)) {
|
||||
this.LogHandlers.Remove(handler);
|
||||
handler.GracefulShutDown();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all log handlers that match the given assembly name
|
||||
/// </summary>
|
||||
/// <returns>Number of log handlers that were unregistered</returns>
|
||||
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
|
||||
/// <summary>
|
||||
/// Gets or sets the global message handler
|
||||
/// </summary>
|
||||
public IMessageHandler MessageHandler {
|
||||
get {
|
||||
return this.messageHandler;
|
||||
}
|
||||
set {
|
||||
this.messageHandler = value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the global log level
|
||||
/// </summary>
|
||||
public LogLevel GlobalLogLevel {
|
||||
public LogLevel LogLevel {
|
||||
get {
|
||||
return this.logLevel;
|
||||
}
|
||||
@ -95,10 +145,13 @@ namespace SimpleLog {
|
||||
this.logLevel = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IMessageFormatter members
|
||||
/// <summary>
|
||||
/// Gets or sets the global date format
|
||||
/// </summary>
|
||||
public string GlobalDateFormat {
|
||||
public string DateFormat {
|
||||
get {
|
||||
return this.dateFormat;
|
||||
}
|
||||
@ -109,17 +162,16 @@ namespace SimpleLog {
|
||||
/// <summary>
|
||||
/// Gets or sets the global line terminator
|
||||
/// </summary>
|
||||
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
|
||||
|
@ -1,12 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SimpleLog {
|
||||
public class MessageHandler {
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -45,10 +45,14 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ILogger.cs" />
|
||||
<Compile Include="IMessageFormatter.cs" />
|
||||
<Compile Include="ILogHandler.cs" />
|
||||
<Compile Include="IMessageHandler.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="MessageHandler.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Util.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
20
SimpleLog/Util.cs
Normal file
20
SimpleLog/Util.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SimpleLog {
|
||||
public static class Util {
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given line terminator is a valid line terminator
|
||||
/// </summary>
|
||||
public static bool LineTerminatorIsValid(string lineTerminator) {
|
||||
return
|
||||
lineTerminator == LineTerminator.Unix ||
|
||||
lineTerminator == LineTerminator.Windows ||
|
||||
lineTerminator == LineTerminator.Mac;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user