Logging: Moved assembly & caller info to one struct 'CallerInformation'

This commit is contained in:
Max 2024-05-04 16:09:11 +02:00
parent 68403245f0
commit e338f91081
8 changed files with 61 additions and 44 deletions

View File

@ -9,7 +9,7 @@ var serilogLogger = SetupSerilog();
LogService.AddLogAdapter(new SerilogAdapter(serilogLogger));
var logger = LogService.RegisterLogger(nameof(Program));
var logger = LogService.RegisterLogger(typeof(Program));
logger.Trace("Test TRACE log! {StringValue} {AnotherValue}", "WOW", "W0W");
logger.Debug("Test DEBUG log! {IntVal}", 69);

View File

@ -15,7 +15,7 @@ public class SerilogAdapter : LogAdapterBase
_messageTemplateParser = new MessageTemplateParser();
}
public const string SampleTemplate = "[{Timestamp:HH:mm:ss} - {Caller} -> {Source}] | {Level:u3}] {Message:lj}{NewLine}{Exception}";
public const string SampleTemplate = "[{Timestamp:HH:mm:ss} - {Caller}] | {Level:u3}] {Message:lj}{NewLine}{Exception}";
private readonly global::Serilog.ILogger _serilogLogger;
private readonly MessageTemplateParser _messageTemplateParser;
@ -24,10 +24,10 @@ public class SerilogAdapter : LogAdapterBase
{
if (capsule == null)
return;
var baseLogger = capsule.Logger as Logger;
var logger = _serilogLogger
.ForContext("Source", baseLogger?.Source.AssemblyName ?? "Static")
.ForContext("Caller", baseLogger?.Identifier);
.ForContext("Assembly", capsule.Logger.Caller.AssemblyName)
.ForContext("Source", capsule.Logger.Caller.Source)
.ForContext("Caller", capsule.Logger.Caller.Name);
var template = _messageTemplateParser.Parse(capsule.Message);
IEnumerable<LogEventProperty>? properties = null;

View File

@ -1,7 +1,7 @@
namespace DotBased.Logging;
/// <summary>
/// The ILogger interface for creating loggers that can be used by the <see cref="LogService"/>
/// ILogger interface used by <see cref="LoggerBase"/>
/// </summary>
public interface ILogger
{

View File

@ -19,5 +19,5 @@ public class LogCapsule
/// <summary>
/// The logger that generated this capsule
/// </summary>
public ILogger Logger { get; set; }
public LoggerBase Logger { get; set; }
}

View File

@ -11,8 +11,8 @@ public class LogOptions
public LogSeverity Severity { get; set; } = LogSeverity.Trace;
/// <summary>
/// The function that will build and return the <see cref="ILogger"/> when calling <see cref="LogService.RegisterLogger"/>, so a custom logger can be used.
/// The function that will build and return the <see cref="LoggerBase"/> when calling <see cref="LogService.RegisterLogger"/>, so a custom logger based on the <see cref="LoggerBase"/> can be used.
/// </summary>
public Func<string, CallingSource, Action<LogCapsule>, ILogger> LoggerBuilder { get; set; } =
(identifier, source, sendEvent) => new Logger(identifier, source, ref sendEvent);
public Func<CallerInformation, Action<LogCapsule>, LoggerBase> LoggerBuilder { get; set; } =
(identifier, sendEvent) => new Logger(identifier, ref sendEvent);
}

View File

@ -46,32 +46,34 @@ public static class LogService
/// }
/// </code>
/// </example>
/// <param name="identifier">The identifier name of the logger, this will be passed to the log adapter as the source.</param>
/// <param name="callerType">The type that called the function</param>
/// <returns>The configured <see cref="ILogger"/> implementation that will be configuered in the <see cref="LogOptions.LoggerBuilder"/> at the <see cref="LogService"/> class</returns>
public static ILogger RegisterLogger(string identifier)
public static ILogger RegisterLogger(Type callerType)
{
var asm = Assembly.GetCallingAssembly();
var logger = Options.LoggerBuilder.Invoke(identifier, CallingSource.LoadFromAsm(asm), _loggerSendEvent);
var logger = Options.LoggerBuilder.Invoke(new CallerInformation(callerType), _loggerSendEvent);
Loggers.Add(logger);
return logger;
}
}
/// <summary>
/// Data struct for holding calling source information.
/// </summary>
public struct CallingSource
{
private CallingSource(Assembly asm)
{
AssemblySource = asm;
var asmName = AssemblySource.GetName();
AssemblyName = asmName.Name ?? "Unknown";
AssemblyFullName = asmName.FullName;
}
public static CallingSource LoadFromAsm(Assembly asm) => new CallingSource(asm);
public Assembly AssemblySource { get; }
public string AssemblyName { get; }
public string AssemblyFullName { get; set; }
public readonly struct CallerInformation
{
public CallerInformation(Type type)
{
Name = type.Name;
Source = type.FullName ?? type.GUID.ToString();
Namespace = type.Namespace ?? string.Empty;
SourceAssembly = type.Assembly;
var asmName = SourceAssembly.GetName();
AssemblyName = asmName.Name ?? "Unknown";
AssemblyFullname = asmName.FullName;
}
public string Name { get; }
public string Source { get; }
public string Namespace { get; }
public Assembly SourceAssembly { get; }
public string AssemblyName { get; }
public string AssemblyFullname { get; }
}

View File

@ -1,21 +1,16 @@
namespace DotBased.Logging;
/// <summary>
/// Main base logger, this class is the default logger that the <see cref="LogService.RegisterLogger"/> function will return.
/// Main logger, this class is the default logger that the <see cref="LogService.RegisterLogger"/> function will return.
/// </summary>
public class Logger(string identifier, CallingSource source, ref Action<LogCapsule> logProcessorHandler) : ILogger
public class Logger(CallerInformation caller, ref Action<LogCapsule> logProcessorHandler) : LoggerBase(caller, ref logProcessorHandler)
{
public string Identifier { get; } = identifier;
public CallingSource Source { get; } = source;
private readonly Action<LogCapsule> _processLog = logProcessorHandler;
public void Log(LogCapsule capsule)
{
_processLog(capsule);
ProcessLog(capsule);
}
public void Trace(string message, params object?[]? parameters)
public override void Trace(string message, params object?[]? parameters)
{
Log(new LogCapsule()
{
@ -27,7 +22,7 @@ public class Logger(string identifier, CallingSource source, ref Action<LogCapsu
});
}
public void Debug(string message, params object?[]? parameters)
public override void Debug(string message, params object?[]? parameters)
{
Log(new LogCapsule()
{
@ -39,7 +34,7 @@ public class Logger(string identifier, CallingSource source, ref Action<LogCapsu
});
}
public void Information(string message, params object?[]? parameters)
public override void Information(string message, params object?[]? parameters)
{
Log(new LogCapsule()
{
@ -51,7 +46,7 @@ public class Logger(string identifier, CallingSource source, ref Action<LogCapsu
});
}
public void Warning(string message, params object?[]? parameters)
public override void Warning(string message, params object?[]? parameters)
{
Log(new LogCapsule()
{
@ -63,7 +58,7 @@ public class Logger(string identifier, CallingSource source, ref Action<LogCapsu
});
}
public void Error(Exception exception, string message, params object?[]? parameters)
public override void Error(Exception exception, string message, params object?[]? parameters)
{
Log(new LogCapsule()
{
@ -76,7 +71,7 @@ public class Logger(string identifier, CallingSource source, ref Action<LogCapsu
});
}
public void Fatal(Exception exception, string message, params object?[]? parameters)
public override void Fatal(Exception exception, string message, params object?[]? parameters)
{
Log(new LogCapsule()
{
@ -89,5 +84,5 @@ public class Logger(string identifier, CallingSource source, ref Action<LogCapsu
});
}
public override int GetHashCode() => HashCode.Combine(Identifier, Source.AssemblyFullName);
public override int GetHashCode() => HashCode.Combine(Caller.Source, Caller.AssemblyFullname);
}

View File

@ -0,0 +1,20 @@
namespace DotBased.Logging;
/// <summary>
/// Base for creating loggers
/// </summary>
/// <param name="caller">The caller information</param>
/// <param name="logProcessorHandler">The handler where the logs can be send to</param>
public abstract class LoggerBase(CallerInformation caller, ref Action<LogCapsule> logProcessorHandler) : ILogger
{
public CallerInformation Caller { get; } = caller;
internal readonly Action<LogCapsule> ProcessLog = logProcessorHandler;
public abstract void Trace(string message, params object?[]? parameters);
public abstract void Debug(string message, params object?[]? parameters);
public abstract void Information(string message, params object?[]? parameters);
public abstract void Warning(string message, params object?[]? parameters);
public abstract void Error(Exception exception, string message, params object?[]? parameters);
public abstract void Fatal(Exception exception, string message, params object?[]? parameters);
}