// Author: Simon Gockner // Created: 2020-02-08 // Copyright(c) 2020 SimonG. All Rights Reserved. using System; using System.Collections.Generic; using System.Reflection; using System.Threading.Tasks; using GBase.Logging.Interfaces; namespace GBase.Logging { /// /// The main logging class /// public class Log : ILog { /// /// Constructor for /// public Log() { Loggers = new List(); } /// /// of s that are subscribed to this /// protected static List Loggers { get; private set; } /// /// The of this logging instance /// protected static LogLevels LogLevel { get; private set; } //TODO: Move LogLevel to ILogger? Allows to set logLevel separately for each ILogger /// /// Initialize the /// /// True if successful, false if not public bool InitializeLog() { return true; } /// /// Set the of the current instance /// /// The public void SetLogLevel(LogLevels logLevel) { LogLevel = logLevel; LogLevelChanged?.Invoke(this, LogLevel); } /// /// Add an to the /// /// The public void AddLogger(ILogger logger) { Loggers.Add(logger); } /// /// Remove an from the /// /// The public void RemoveLogger(ILogger logger) { Loggers.Remove(logger); } /// /// Write a given to the set s /// /// The /// The of the caller public static async Task Write(Exception ex) { ILogComponent component = GetDefaultComponentFromType(); await Write(component, LogLevels.Error, ex.Message); await Write(component, LogLevels.Error, ""); await Write(component, LogLevels.Error, ex.StackTrace); } /// /// Write a given to the set s /// /// The /// The public static async Task Write(ILogComponent component, Exception ex) { await Write(component, LogLevels.Error, ex.Message); await Write(component, LogLevels.Error, ""); await Write(component, LogLevels.Error, ex.StackTrace); } /// /// Write a given to the set s /// /// The /// The of the caller public static async Task Write(AggregateException ex) { ILogComponent component = GetDefaultComponentFromType(); await Write(component, LogLevels.Error, ex.Message); await Write(component, LogLevels.Error, ""); await Write(component, LogLevels.Error, ex.StackTrace); await Write(component, LogLevels.Error, ""); foreach (var innerException in ex.InnerExceptions) { await Write(component, innerException); await Write(component, LogLevels.Error, ""); } } /// /// Write a given with the to the set s /// /// /// The of the caller public static async Task Write(string line) { ILogComponent component = GetDefaultComponentFromType(); await Write(component, LogLevels.Default, line); } /// /// Write a given with the of the calling and the to the set s /// /// The /// The given /// The of the caller public static async Task Write(LogLevels logLevel, string line) { ILogComponent component = GetDefaultComponentFromType(); await Write(component, logLevel, line); } /// /// Write a given with the and the to the set s /// /// The /// The /// The given public static async Task Write(ILogComponent component, LogLevels logLevel, string line) { if (logLevel > LogLevel) //logLevel of the message can't be higher than the set LogLevel return; ILogMessage message = new LogMessage() { LogLevel = logLevel, Timestamp = DateTime.Now, Component = component, Message = line }; foreach (var logger in Loggers) { await logger.Write(message); } } /// /// Get the default for the given /// /// The /// protected static ILogComponent GetDefaultComponentFromType() { Assembly assembly = Assembly.GetAssembly(typeof(T)); LogComponentAttribute attribute = assembly.GetCustomAttribute(); return attribute ?? new LogComponentAttribute("UNKNOWN"); } /// /// the /// public async ValueTask DisposeAsync() { foreach (var logger in Loggers) { await logger.DisposeAsync(); } Loggers.Clear(); LogLevel = LogLevels.None; } /// /// Event that is fired when is called /// is the newly set /// public static event EventHandler LogLevelChanged; } }