// 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)
{
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
/// 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;
}
}