// Author: Gockner, Simon // Created: 2019-09-26 // Copyright(c) 2019 SimonG. All Rights Reserved. using System; using System.Collections.Generic; using System.Reflection; using System.Threading.Tasks; using Lib.Logging.Exceptions; using Lib.Logging.Interfaces; using Lib.Logging.Loggers.Interfaces; using Lib.Tools; namespace Lib.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; } = LogLevels.Default; //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) => await Write(GetDefaultComponentFromType(), ex); /// /// 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, ""); if (ex.StackTrace != null) 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, ""); if (ex.StackTrace != null) { 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) => await Write(GetDefaultComponentFromType(), logLevel, line); /// /// Write a given with the and the to the set s /// /// The /// The /// The given /// Log is not initialized yet 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 }; if (Loggers == null) throw new LogNotInitializedException(); 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"); } /// /// Write a header to all loggers /// /// A to wait on public async Task WriteLogHeader() { await Write($"Mystify {Versions.GetVersion()}"); await Write($"User: {Environment.UserName}"); await Write($"Date: {DateTime.Today:dd.MM.yyyy}"); await Write($"OS: {Environment.OSVersion}"); await Write($"CLR-Version: {Environment.Version}"); await Write(""); } /// /// the /// public async ValueTask DisposeAsync() { if (Loggers != null) { 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; } }