using System; using System.Collections.Generic; using System.Text; namespace ExtremelySimpleLogger { /// /// The implementation of a logger, which is a wrapper class around multiple logging . /// To start logging with a logger, its need to be initialized. /// public class Logger : IDisposable { /// /// All of the instances that this logger logs to. /// By default, , , and are available. /// public List Sinks { get; set; } = new List(); /// /// The minimum that a message needs to have for this logger to log it. /// public LogLevel MinimumLevel { get; set; } = LogLevel.Trace; /// /// The with which log messages should be formatted by a if its is . /// By default, is used. /// public LogFormatter DefaultFormatter { get; set; } = Logger.FormatDefault; /// /// If this property is set to false, this logger will not log any messages. /// public bool IsEnabled { get; set; } = true; /// /// The name of this logger. This name is used in by default. /// public string Name { get; set; } /// /// Initializes a new logger with the given name. /// Note that, for this logger to do anything, its need to be initialized. /// /// The logger's name public Logger(string name = "") { this.Name = name; } /// /// Logs a message, passing it on to this logger's . /// /// The importance level of this message /// The message /// An optional exception whose stack trace will be appended to the message public void Log(LogLevel level, object message, Exception e = null) { if (!this.IsEnabled || level < this.MinimumLevel) return; foreach (var sink in this.Sinks) { if (sink.IsEnabled && level >= sink.MinimumLevel) sink.Log(this, level, message, e); } } /// /// Logs a message with the log level. /// /// The message public void Trace(object message) => this.Log(LogLevel.Trace, message); /// /// Logs a message with the log level. /// /// The message public void Debug(object message) => this.Log(LogLevel.Debug, message); /// /// Logs a message with the log level. /// /// The message public void Info(object message) => this.Log(LogLevel.Info, message); /// /// Logs a message with the log level. /// /// The message /// An optional exception whose stack trace will be appended to the message public void Warn(object message, Exception e = null) => this.Log(LogLevel.Warn, message, e); /// /// Logs a message with the log level. /// /// The message /// An optional exception whose stack trace will be appended to the message public void Error(object message, Exception e = null) => this.Log(LogLevel.Error, message, e); /// /// Logs a message with the log level. /// /// The message /// An optional exception whose stack trace will be appended to the message public void Fatal(object message, Exception e = null) => this.Log(LogLevel.Fatal, message, e); /// /// Disposes this logger, freeing all of the resources associated with its . /// public void Dispose() { foreach (var sink in this.Sinks) sink.Dispose(); } /// /// The default formatter for logging messages, which is 's initial value. /// By default, messages are laid out as follows: /// /// [Date and time] [Logger name, if set] [Log level] Message /// Exception, if set /// /// /// The logger that the message was passed to /// The importance level of this message /// The message /// An optional exception whose stack trace will be appended to the message /// A formatted string to log public static string FormatDefault(Logger logger, LogLevel level, object message, Exception e = null) { var builder = new StringBuilder(); // date builder.Append($"[{DateTime.Now}] "); // logger name if (!string.IsNullOrEmpty(logger.Name)) builder.Append($"[{logger.Name}] "); // log level builder.Append($"[{level}] "); // message builder.Append(message); // stack trace if (e != null) builder.Append($"\n{e}"); return builder.ToString(); } } /// /// A delegate method used by and . /// /// The logger that the message was passed to /// The importance level of this message /// The message /// An optional exception whose stack trace will be appended to the message public delegate string LogFormatter(Logger logger, LogLevel level, object message, Exception e = null); }