389 lines
11 KiB
C#
389 lines
11 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using JD.Collections.Extensions;
|
|
using JD.Kernel.Classes;
|
|
using JD.Kernel.StaticHelpers;
|
|
using JD.Kernel.Structs;
|
|
|
|
namespace JD.LogService
|
|
{
|
|
/// <summary>
|
|
/// A <see cref="LoggingContext"/> is used to aggregate message, warnings and errors in a list.
|
|
/// </summary>
|
|
public class LoggingContext : ILogger
|
|
{
|
|
#region Inner Types
|
|
|
|
/// <summary>
|
|
/// An add-only list.
|
|
/// </summary>
|
|
private class List<T> : Collection<T> where T : LogEvent
|
|
{
|
|
#region Variables
|
|
|
|
private readonly LoggingContext m_parent;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
public List(LoggingContext parent)
|
|
{
|
|
m_parent = parent;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
/// <summary>
|
|
/// The function invoked when the user inserts an item in the list, it will be handled by our parent.
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <param name="item"></param>
|
|
protected override void InsertItem(int index, T item)
|
|
{
|
|
m_parent.Log(item);
|
|
}
|
|
|
|
protected override void ClearItems()
|
|
{
|
|
throw new InvalidOperationException("Can only add items to the list.");
|
|
}
|
|
|
|
protected override void RemoveItem(int index)
|
|
{
|
|
throw new InvalidOperationException("Can only add items to the list.");
|
|
}
|
|
|
|
protected override void SetItem(int index, T item)
|
|
{
|
|
throw new InvalidOperationException("Can only add items to the list.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Function invoked when the parent inserts an item in the list, it simply insert the item.
|
|
/// </summary>
|
|
public void AddInternal(T item)
|
|
{
|
|
ICollection baseCollection = this;
|
|
lock (baseCollection.SyncRoot)
|
|
{
|
|
base.InsertItem(Count, item);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Accompanies the BeforeEventLogged event.
|
|
/// </summary>
|
|
public class BeforeEventLoggedEventArgs : CancelEventArgs
|
|
{
|
|
#region Variables
|
|
|
|
private LogEvent m_event;
|
|
|
|
#endregion
|
|
|
|
#region Constructors
|
|
|
|
/// <summary>
|
|
/// Ctor.
|
|
/// </summary>
|
|
/// <param name="event"></param>
|
|
public BeforeEventLoggedEventArgs(LogEvent @event)
|
|
{
|
|
m_event = @event;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// The event beeing logged (can be swapped).
|
|
/// </summary>
|
|
public LogEvent Event
|
|
{
|
|
get { return m_event; }
|
|
set
|
|
{
|
|
Throw.IfNull(value, "value");
|
|
m_event = value;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Variables
|
|
|
|
private readonly List<LogEvent> m_log;
|
|
private readonly List<Error> m_errors;
|
|
private readonly List<Error> m_warnings;
|
|
private readonly List<Message> m_messages;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
/// <summary>
|
|
/// Constructor.
|
|
/// </summary>
|
|
public LoggingContext()
|
|
{
|
|
m_errors = new List<Error>(this);
|
|
m_warnings = new List<Error>(this);
|
|
m_messages = new List<Message>(this);
|
|
m_log = new List<LogEvent>(this);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// Accesses the collection of errors.
|
|
/// </summary>
|
|
public IList<Error> Errors
|
|
{
|
|
get { return m_errors; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Accesses the collection of warnings (non critical errors).
|
|
/// </summary>
|
|
public IList<Error> Warnings
|
|
{
|
|
get { return m_warnings; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Accesses the collection of messages.
|
|
/// </summary>
|
|
public IList<Message> Messages
|
|
{
|
|
get { return m_messages; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Accesses the entire collection of all the log events.
|
|
/// </summary>
|
|
public IList<LogEvent> FullLog
|
|
{
|
|
get { return m_log; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Events
|
|
|
|
/// <summary>
|
|
/// Triggered when an error is added in <see cref="Errors"/>.
|
|
/// </summary>
|
|
public event EventHandler<ItemEventArgs<Error>> ErrorAdded;
|
|
|
|
/// <summary>
|
|
/// Triggers the <see cref="ErrorAdded"/> event.
|
|
/// </summary>
|
|
/// <param name="e">Event Args.</param>
|
|
protected virtual void OnErrorAdded(ItemEventArgs<Error> e)
|
|
{
|
|
ErrorAdded?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggered when a warning is added in <see cref="Warnings"/>.
|
|
/// </summary>
|
|
public event EventHandler<ItemEventArgs<Error>> WarningAdded;
|
|
|
|
/// <summary>
|
|
/// Triggers the <see cref="WarningAdded"/> event.
|
|
/// </summary>
|
|
/// <param name="e">Event Args.</param>
|
|
protected virtual void OnWarningAdded(ItemEventArgs<Error> e)
|
|
{
|
|
WarningAdded?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggered when a message is added in <see cref="Messages"/>.
|
|
/// </summary>
|
|
public event EventHandler<ItemEventArgs<Message>> MessageAdded;
|
|
|
|
/// <summary>
|
|
/// Triggers the <see cref="MessageAdded"/> event.
|
|
/// </summary>
|
|
/// <param name="e">Event Args.</param>
|
|
protected virtual void OnMessageAdded(ItemEventArgs<Message> e)
|
|
{
|
|
MessageAdded?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggered when a item is logged in <see cref="FullLog"/>.
|
|
/// </summary>
|
|
public event EventHandler<ItemEventArgs<LogEvent>> EventLogged;
|
|
|
|
/// <summary>
|
|
/// Triggers the <see cref="EventLogged"/> event.
|
|
/// </summary>
|
|
/// <param name="e">Event Args.</param>
|
|
protected virtual void OnEventLogged(ItemEventArgs<LogEvent> e)
|
|
{
|
|
EventLogged?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggered before an item is logged in <see cref="FullLog"/>.
|
|
/// </summary>
|
|
public event EventHandler<BeforeEventLoggedEventArgs> BeforeEventLogged;
|
|
|
|
/// <summary>
|
|
/// Triggers the <see cref="BeforeEventLogged"/> event.
|
|
/// </summary>
|
|
/// <param name="e">Event Args.</param>
|
|
protected virtual void OnBeforeEventLogged(BeforeEventLoggedEventArgs e)
|
|
{
|
|
BeforeEventLogged?.Invoke(this, e);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ILogger Members
|
|
|
|
/// <summary>
|
|
/// Log an event in the logger.
|
|
/// </summary>
|
|
/// <param name="event"></param>
|
|
/// <remarks>The event will be dispatched in the correct collection.</remarks>
|
|
public void Log(LogEvent @event)
|
|
{
|
|
Throw.IfNull(@event, "event");
|
|
|
|
BeforeEventLoggedEventArgs args = new BeforeEventLoggedEventArgs(@event);
|
|
OnBeforeEventLogged(args);
|
|
|
|
if (args.Cancel)
|
|
{
|
|
return;
|
|
}
|
|
|
|
@event = args.Event;
|
|
|
|
m_log.AddInternal(@event);
|
|
OnEventLogged(new ItemEventArgs<LogEvent>(@event));
|
|
|
|
switch (@event.Category)
|
|
{
|
|
case LogCategory.Message:
|
|
Message message = @event as Message;
|
|
Trace.Assert(message != null);
|
|
|
|
m_messages.AddInternal(message);
|
|
OnMessageAdded(new ItemEventArgs<Message>(message));
|
|
break;
|
|
|
|
case LogCategory.Warning:
|
|
Error warning = @event as Error;
|
|
Trace.Assert(warning != null);
|
|
|
|
m_warnings.AddInternal(warning);
|
|
OnWarningAdded(new ItemEventArgs<Error>(warning));
|
|
break;
|
|
|
|
case LogCategory.Error:
|
|
Error error = @event as Error;
|
|
Trace.Assert(error != null);
|
|
|
|
m_errors.AddInternal(error);
|
|
OnErrorAdded(new ItemEventArgs<Error>(error));
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Static methods
|
|
|
|
/// <summary>
|
|
/// Creates a logging context that redirects all its inputs to the given logger.
|
|
/// </summary>
|
|
/// <param name="logger">Logger to redirect to.</param>
|
|
/// <returns></returns>
|
|
public static LoggingContext FromLogger(ILogger logger)
|
|
{
|
|
LoggingContext context = new LoggingContext();
|
|
context.EventLogged += delegate(object sender, ItemEventArgs<LogEvent> e)
|
|
{
|
|
logger.Log(e.Item);
|
|
};
|
|
return context;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a logger that logs to the console.
|
|
/// </summary>
|
|
public static LoggingContext CreateConsoleLogger()
|
|
{
|
|
LoggingContext result = new LoggingContext();
|
|
ILogger consoleLogger = Logger.CreateConsoleLogger();
|
|
|
|
result.EventLogged += (sender, e) => consoleLogger.Log(e.Item);
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Logging Helper
|
|
|
|
/// <summary>
|
|
/// Log an event in the logger.
|
|
/// </summary>
|
|
/// <param name="category"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
[Obsolete("Use the extension methods on ILogger instead (LogError, LogWarning, LogMessage).")] // 2011.01
|
|
public LogEvent Log(LogCategory category, string message, params object[] args)
|
|
{
|
|
LogEvent @event = LogEvent.Formatted(category, message, args);
|
|
Log(@event);
|
|
return @event;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Log an event in the logger.
|
|
/// </summary>
|
|
/// <param name="category"></param>
|
|
/// <param name="origin"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
[Obsolete("Use the extension methods on ILogger instead (LogError, LogWarning, LogMessage).")] // 2011.01
|
|
public LogEvent Log(LogCategory category, FileLocation origin, string message, params object[] args)
|
|
{
|
|
LogEvent @event = LogEvent.Formatted(category, origin, message, args);
|
|
Log(@event);
|
|
return @event;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs the content of the given logging context into this one.
|
|
/// </summary>
|
|
/// <param name="log"></param>
|
|
public void Log(LoggingContext log)
|
|
{
|
|
log.FullLog.ForEach(Log);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|