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 {
|
public interface ILogHandler {
|
||||||
|
|
||||||
bool Log(object message, LogLevel level);
|
bool Log(object message, LogLevel level);
|
||||||
string Context { get; set; }
|
|
||||||
LogLevel? LogLevel { 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 {
|
public struct LineTerminator {
|
||||||
|
/// <summary>
|
||||||
|
/// Windows line terminator (CRLF)
|
||||||
|
/// </summary>
|
||||||
public static readonly string Windows = "\r\n";
|
public static readonly string Windows = "\r\n";
|
||||||
|
/// <summary>
|
||||||
|
/// Macintosh line terminator (CR)
|
||||||
|
/// </summary>
|
||||||
public static readonly string Mac = "\r";
|
public static readonly string Mac = "\r";
|
||||||
|
/// <summary>
|
||||||
|
/// Unix line terminator (LF)
|
||||||
|
/// </summary>
|
||||||
public static readonly string Unix = "\n";
|
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();
|
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 List<ILogHandler> LogHandlers;
|
||||||
|
protected IMessageHandler messageHandler;
|
||||||
protected LogLevel logLevel;
|
protected LogLevel logLevel;
|
||||||
protected string dateFormat;
|
protected string dateFormat;
|
||||||
protected string lineTerminator;
|
protected string lineTerminator;
|
||||||
public bool Enabled;
|
|
||||||
|
|
||||||
private Logger() {
|
private Logger() {
|
||||||
this.LogHandlers = new List<ILogHandler>();
|
this.LogHandlers = new List<ILogHandler>();
|
||||||
this.logLevel = LogLevel.Warning;
|
this.logLevel = LogLevel.Warning;
|
||||||
this.dateFormat = "YYYY-MM-dd HH:ii:ss";
|
this.lineTerminator = SimpleLog.LineTerminator.Unix;
|
||||||
this.lineTerminator = LineTerminator.Unix;
|
|
||||||
this.Enabled = true;
|
this.Enabled = true;
|
||||||
|
this.messageHandler = new DefaultMessageHandler();
|
||||||
|
this.dateFormat = "YYYY-MM-dd HH:ii:ss";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region ILogger members
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Logs a message at the specified log level
|
/// Logs a message at the specified log level
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -47,12 +67,15 @@ namespace SimpleLog {
|
|||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
if (this.Enabled) {
|
if (this.Enabled) {
|
||||||
string convertedMessage = this.ConvertMessageToString(message);
|
string convertedMessage;
|
||||||
|
LogLevel allowedLevel;
|
||||||
|
IMessageHandler messageHandler;
|
||||||
foreach (ILogHandler handler in this.LogHandlers) {
|
foreach (ILogHandler handler in this.LogHandlers) {
|
||||||
LogLevel allowedLevel = handler.LogLevel ?? this.GlobalLogLevel;
|
allowedLevel = handler.LogLevel ?? this.LogLevel;
|
||||||
if (level <= allowedLevel) {
|
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));
|
success = (success && handler.Log(convertedMessage, allowedLevel));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,34 +83,61 @@ namespace SimpleLog {
|
|||||||
|
|
||||||
return success;
|
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) {
|
/// <summary>
|
||||||
string dateFormat = handler.DateFormat ?? this.GlobalDateFormat;
|
/// Registers a log handler with this logger
|
||||||
string timestamp = string.Format("{0:" + dateFormat + "}", DateTime.Now);
|
/// </summary>
|
||||||
return timestamp;
|
/// <param name="handler">The log handler to register</param>
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterLogHandler(ILogHandler handler) {
|
public void RegisterLogHandler(ILogHandler handler) {
|
||||||
this.LogHandlers.Add(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
|
#region Accessors
|
||||||
/// <summary>
|
/// <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
|
/// Gets or sets the global log level
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LogLevel GlobalLogLevel {
|
public LogLevel LogLevel {
|
||||||
get {
|
get {
|
||||||
return this.logLevel;
|
return this.logLevel;
|
||||||
}
|
}
|
||||||
@ -95,10 +145,13 @@ namespace SimpleLog {
|
|||||||
this.logLevel = value;
|
this.logLevel = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IMessageFormatter members
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the global date format
|
/// Gets or sets the global date format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string GlobalDateFormat {
|
public string DateFormat {
|
||||||
get {
|
get {
|
||||||
return this.dateFormat;
|
return this.dateFormat;
|
||||||
}
|
}
|
||||||
@ -109,17 +162,16 @@ namespace SimpleLog {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the global line terminator
|
/// Gets or sets the global line terminator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string GlobalLineTerminator {
|
public string LineTerminator {
|
||||||
get {
|
get {
|
||||||
return this.lineTerminator;
|
return this.lineTerminator;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if (value == LineTerminator.Unix || value == LineTerminator.Windows || value == LineTerminator.Mac) {
|
if (!Util.LineTerminatorIsValid(value)) {
|
||||||
this.lineTerminator = value;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new ArgumentException("Invalid line terminator; see SimpleLog.LineTerminator struct for valid line terminators");
|
throw new ArgumentException("Invalid line terminator; see SimpleLog.LineTerminator struct for valid line terminators");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.lineTerminator = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#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" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="ILogger.cs" />
|
||||||
|
<Compile Include="IMessageFormatter.cs" />
|
||||||
<Compile Include="ILogHandler.cs" />
|
<Compile Include="ILogHandler.cs" />
|
||||||
|
<Compile Include="IMessageHandler.cs" />
|
||||||
<Compile Include="Logger.cs" />
|
<Compile Include="Logger.cs" />
|
||||||
<Compile Include="MessageHandler.cs" />
|
<Compile Include="MessageHandler.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Util.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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