Integrate AcLogger with Microsoft.Extensions.Logging
AyCode.Core loggers now implement the ILogger interface, enabling direct integration with Microsoft.Extensions.Logging. Added AcLoggerProvider and extension methods for easy DI registration. Internal LogLevel usages are now AcLogLevel to avoid confusion. This allows seamless use of AyCode loggers in ASP.NET Core and other .NET apps using standard logging abstractions.
This commit is contained in:
parent
46c12bf5be
commit
028c80db94
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MessagePack" Version="3.1.4" />
|
<PackageReference Include="MessagePack" Version="3.1.4" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.5" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
<PackageReference Include="MessagePack" Version="3.1.4" />
|
<PackageReference Include="MessagePack" Version="3.1.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.11" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.11" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.11" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.11" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.5" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AyCode.Core.Loggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ILoggerProvider implementation that creates logger instances using AcLoggerBase.
|
||||||
|
/// Since AcLoggerBase now implements ILogger directly, this provider just wraps
|
||||||
|
/// the base logger with category-specific instances.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class AcLoggerProvider<TLogger> : ILoggerProvider where TLogger : AcLoggerBase
|
||||||
|
{
|
||||||
|
private readonly Func<string, TLogger> _loggerFactory;
|
||||||
|
private readonly ConcurrentDictionary<string, TLogger> _loggers = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a provider that uses a factory function to create category-specific loggers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loggerFactory">Factory function that creates a logger for a given category name.</param>
|
||||||
|
public AcLoggerProvider(Func<string, TLogger> loggerFactory)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(loggerFactory);
|
||||||
|
_loggerFactory = loggerFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILogger CreateLogger(string categoryName)
|
||||||
|
{
|
||||||
|
return _loggers.GetOrAdd(categoryName, _loggerFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_loggers.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods for registering AcLogger with Microsoft's DI and logging infrastructure.
|
||||||
|
/// </summary>
|
||||||
|
public static class AcLoggerExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds AcLogger as a logging provider using a factory function.
|
||||||
|
/// The factory receives the category name and should return a configured logger instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// builder.Logging.AddAcLogger(categoryName => new MyLogger(categoryName));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
public static ILoggingBuilder AddAcLogger<TLogger>(this ILoggingBuilder builder, Func<string, TLogger> loggerFactory)
|
||||||
|
where TLogger : AcLoggerBase
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(builder);
|
||||||
|
ArgumentNullException.ThrowIfNull(loggerFactory);
|
||||||
|
|
||||||
|
builder.AddProvider(new AcLoggerProvider<TLogger>(loggerFactory));
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears default providers and adds only AcLogger.
|
||||||
|
/// Use this if you want ONLY your logger, not Microsoft's console/debug loggers.
|
||||||
|
/// </summary>
|
||||||
|
public static ILoggingBuilder UseOnlyAcLogger<TLogger>(this ILoggingBuilder builder, Func<string, TLogger> loggerFactory)
|
||||||
|
where TLogger : AcLoggerBase
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(builder);
|
||||||
|
ArgumentNullException.ThrowIfNull(loggerFactory);
|
||||||
|
|
||||||
|
builder.ClearProviders();
|
||||||
|
builder.AddProvider(new AcLoggerProvider<TLogger>(loggerFactory));
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,10 @@ using System.Security.AccessControl;
|
||||||
using AyCode.Core.Consts;
|
using AyCode.Core.Consts;
|
||||||
using AyCode.Core.Enums;
|
using AyCode.Core.Enums;
|
||||||
using AyCode.Utils.Extensions;
|
using AyCode.Utils.Extensions;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using static System.Net.Mime.MediaTypeNames;
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
using AcLogLevel = AyCode.Core.Loggers.LogLevel;
|
||||||
|
using MsLogLevel = Microsoft.Extensions.Logging.LogLevel;
|
||||||
|
|
||||||
namespace AyCode.Core.Loggers;
|
namespace AyCode.Core.Loggers;
|
||||||
|
|
||||||
|
|
@ -12,11 +15,18 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
{
|
{
|
||||||
protected readonly List<IAcLogWriterBase> LogWriters = [];
|
protected readonly List<IAcLogWriterBase> LogWriters = [];
|
||||||
|
|
||||||
public LogLevel LogLevel { get; set; } = LogLevel.Error;
|
public AcLogLevel LogLevel { get; set; } = AcLogLevel.Error;
|
||||||
public AppType AppType { get; set; } = AppType.Server;
|
public AppType AppType { get; set; } = AppType.Server;
|
||||||
|
|
||||||
public string? CategoryName { get; set; }
|
public string? CategoryName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, long category names (e.g., "Microsoft.AspNetCore.SignalR.HubConnectionHandler")
|
||||||
|
/// will be shortened to just the class name (e.g., "HubConnectionHandler").
|
||||||
|
/// Default is true for consistency with typeof(T).Name usage.
|
||||||
|
/// </summary>
|
||||||
|
public bool ShortenCategoryNames { get; set; } = true;
|
||||||
|
|
||||||
protected AcLoggerBase() : this(null)
|
protected AcLoggerBase() : this(null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +36,7 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
CategoryName = categoryName ?? "...";
|
CategoryName = categoryName ?? "...";
|
||||||
|
|
||||||
AppType = AcEnv.AppConfiguration.GetEnum<AppType>("AyCode:Logger:AppType");
|
AppType = AcEnv.AppConfiguration.GetEnum<AppType>("AyCode:Logger:AppType");
|
||||||
LogLevel = AcEnv.AppConfiguration.GetEnum<LogLevel>("AyCode:Logger:LogLevel");
|
LogLevel = AcEnv.AppConfiguration.GetEnum<AcLogLevel>("AyCode:Logger:LogLevel");
|
||||||
|
|
||||||
foreach (var logWriterSection in AcEnv.AppConfiguration.GetSection("AyCode:Logger:LogWriters").GetChildren())
|
foreach (var logWriterSection in AcEnv.AppConfiguration.GetSection("AyCode:Logger:LogWriters").GetChildren())
|
||||||
{
|
{
|
||||||
|
|
@ -41,7 +51,7 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var logWriterLogLevel = logWriterSection.GetEnum<LogLevel>("LogLevel");
|
var logWriterLogLevel = logWriterSection.GetEnum<AcLogLevel>("LogLevel");
|
||||||
|
|
||||||
if (Activator.CreateInstance(logWriterType, AppType, logWriterLogLevel, CategoryName) is IAcLogWriterBase logWriter) LogWriters.Add(logWriter);
|
if (Activator.CreateInstance(logWriterType, AppType, logWriterLogLevel, CategoryName) is IAcLogWriterBase logWriter) LogWriters.Add(logWriter);
|
||||||
else Console.Error.WriteLine($"{GetType().Name}; Can't create logWriterType instance; logWriterType: {logWriterType?.AssemblyQualifiedName};");
|
else Console.Error.WriteLine($"{GetType().Name}; Can't create logWriterType instance; logWriterType: {logWriterType?.AssemblyQualifiedName};");
|
||||||
|
|
@ -54,11 +64,11 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AcLoggerBase(string? categoryName, params IAcLogWriterBase[] logWriters) :
|
protected AcLoggerBase(string? categoryName, params IAcLogWriterBase[] logWriters) :
|
||||||
this(AcEnv.AppConfiguration.GetEnum<AppType>("AyCode:Logger:AppType"), AcEnv.AppConfiguration.GetEnum<LogLevel>("AyCode:Logger:LogLevel"), categoryName, logWriters)
|
this(AcEnv.AppConfiguration.GetEnum<AppType>("AyCode:Logger:AppType"), AcEnv.AppConfiguration.GetEnum<AcLogLevel>("AyCode:Logger:LogLevel"), categoryName, logWriters)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AcLoggerBase(AppType appType, LogLevel logLevel, string? categoryName, params IAcLogWriterBase[] logWriters)
|
protected AcLoggerBase(AppType appType, AcLogLevel logLevel, string? categoryName, params IAcLogWriterBase[] logWriters)
|
||||||
{
|
{
|
||||||
AppType = appType;
|
AppType = appType;
|
||||||
LogLevel = logLevel;
|
LogLevel = logLevel;
|
||||||
|
|
@ -72,9 +82,11 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
public List<IAcLogWriterBase> GetWriters => [.. LogWriters];
|
public List<IAcLogWriterBase> GetWriters => [.. LogWriters];
|
||||||
public TLogWriter? Writer<TLogWriter>() where TLogWriter : IAcLogWriterBase => LogWriters.OfType<TLogWriter>().FirstOrDefault();
|
public TLogWriter? Writer<TLogWriter>() where TLogWriter : IAcLogWriterBase => LogWriters.OfType<TLogWriter>().FirstOrDefault();
|
||||||
|
|
||||||
|
#region IAcLogWriterBase Implementation
|
||||||
|
|
||||||
public virtual void Detail(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
public virtual void Detail(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
||||||
{
|
{
|
||||||
if (LogLevel <= LogLevel.Detail) LogWriters.ForEach(x => x.Detail(text, categoryName ?? CategoryName, memberName));
|
if (LogLevel <= AcLogLevel.Detail) LogWriters.ForEach(x => x.Detail(text, categoryName ?? CategoryName, memberName));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
|
|
@ -83,7 +95,7 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
|
|
||||||
public virtual void Debug(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
public virtual void Debug(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
||||||
{
|
{
|
||||||
if (LogLevel <= LogLevel.Debug) LogWriters.ForEach(x => x.Debug(text, categoryName ?? CategoryName, memberName));
|
if (LogLevel <= AcLogLevel.Debug) LogWriters.ForEach(x => x.Debug(text, categoryName ?? CategoryName, memberName));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
|
|
@ -92,7 +104,7 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
|
|
||||||
public virtual void Info(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
public virtual void Info(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
||||||
{
|
{
|
||||||
if (LogLevel <= LogLevel.Info) LogWriters.ForEach(x => x.Info(text, categoryName ?? CategoryName, memberName));
|
if (LogLevel <= AcLogLevel.Info) LogWriters.ForEach(x => x.Info(text, categoryName ?? CategoryName, memberName));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
|
|
@ -101,7 +113,7 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
|
|
||||||
public virtual void Warning(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
public virtual void Warning(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
||||||
{
|
{
|
||||||
if (LogLevel <= LogLevel.Warning) LogWriters.ForEach(x => x.Warning(text, categoryName ?? CategoryName, memberName));
|
if (LogLevel <= AcLogLevel.Warning) LogWriters.ForEach(x => x.Warning(text, categoryName ?? CategoryName, memberName));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
|
|
@ -110,7 +122,7 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
|
|
||||||
public virtual void Suggest(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
public virtual void Suggest(string? text, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
||||||
{
|
{
|
||||||
if (LogLevel <= LogLevel.Suggest) LogWriters.ForEach(x => x.Suggest(text, categoryName ?? CategoryName, memberName));
|
if (LogLevel <= AcLogLevel.Suggest) LogWriters.ForEach(x => x.Suggest(text, categoryName ?? CategoryName, memberName));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
|
|
@ -119,37 +131,36 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
|
|
||||||
public virtual void Error(string? text, Exception? ex = null, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
public virtual void Error(string? text, Exception? ex = null, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
||||||
{
|
{
|
||||||
if (LogLevel <= LogLevel.Error) LogWriters.ForEach(x => x.Error(text, ex, categoryName ?? CategoryName, memberName));
|
if (LogLevel <= AcLogLevel.Error) LogWriters.ForEach(x => x.Error(text, ex, categoryName ?? CategoryName, memberName));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
public void ErrorConditional(string? text, Exception? ex = null, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
public void ErrorConditional(string? text, Exception? ex = null, string? categoryName = null, [CallerMemberName] string? memberName = null)
|
||||||
=> Error(text, ex, categoryName, memberName);
|
=> Error(text, ex, categoryName, memberName);
|
||||||
|
|
||||||
public void Write(AppType appType, LogLevel logLevel, string? logText, string? callerMemberName, string? categoryName)
|
public void Write(AppType appType, AcLogLevel logLevel, string? logText, string? callerMemberName, string? categoryName)
|
||||||
=> Write(appType, logLevel, logText, callerMemberName, categoryName, null, null);
|
=> Write(appType, logLevel, logText, callerMemberName, categoryName, null, null);
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
public void WriteConditional(AppType appType, LogLevel logLevel, string? logText, string? callerMemberName, string? categoryName)
|
public void WriteConditional(AppType appType, AcLogLevel logLevel, string? logText, string? callerMemberName, string? categoryName)
|
||||||
=> Write(appType, logLevel, logText, callerMemberName, categoryName, null, null);
|
=> Write(appType, logLevel, logText, callerMemberName, categoryName, null, null);
|
||||||
|
|
||||||
public void Write(AppType appType, LogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, Exception? ex)
|
public void Write(AppType appType, AcLogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, Exception? ex)
|
||||||
=> Write(appType, logLevel, logText, callerMemberName, categoryName, ex?.GetType().Name, ex?.ToString());
|
=> Write(appType, logLevel, logText, callerMemberName, categoryName, ex?.GetType().Name, ex?.ToString());
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
public void WriteConditional(AppType appType, LogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, Exception? ex)
|
public void WriteConditional(AppType appType, AcLogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, Exception? ex)
|
||||||
=> Write(appType, logLevel, logText, callerMemberName, categoryName, ex);
|
=> Write(appType, logLevel, logText, callerMemberName, categoryName, ex);
|
||||||
|
|
||||||
public virtual void Write(AppType appType, LogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, string? errorType, string? exMessage)
|
public virtual void Write(AppType appType, AcLogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, string? errorType, string? exMessage)
|
||||||
{
|
{
|
||||||
if (LogLevel <= logLevel) LogWriters.ForEach(x => x.Write(appType, logLevel, logText, callerMemberName, categoryName ?? CategoryName, errorType, exMessage));
|
if (LogLevel <= logLevel) LogWriters.ForEach(x => x.Write(appType, logLevel, logText, callerMemberName, categoryName ?? CategoryName, errorType, exMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
public void WriteConditional(AppType appType, LogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, string? errorType, string? exMessage)
|
public void WriteConditional(AppType appType, AcLogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, string? errorType, string? exMessage)
|
||||||
=> Write(appType, logLevel, logText, callerMemberName, categoryName, errorType, exMessage);
|
=> Write(appType, logLevel, logText, callerMemberName, categoryName, errorType, exMessage);
|
||||||
|
|
||||||
|
|
||||||
public void Write(IAcLogItemClient logItem)
|
public void Write(IAcLogItemClient logItem)
|
||||||
{
|
{
|
||||||
if (LogLevel <= logItem.LogLevel) LogWriters.ForEach(x => x.Write(logItem));
|
if (LogLevel <= logItem.LogLevel) LogWriters.ForEach(x => x.Write(logItem));
|
||||||
|
|
@ -157,4 +168,110 @@ public abstract class AcLoggerBase : IAcLoggerBase
|
||||||
|
|
||||||
[Conditional("DEBUG")]
|
[Conditional("DEBUG")]
|
||||||
public void WriteConditional(IAcLogItemClient logItem) => Write(logItem);
|
public void WriteConditional(IAcLogItemClient logItem) => Write(logItem);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ILogger Implementation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ILogger.BeginScope - AcLoggerBase doesn't support scopes, returns no-op disposable.
|
||||||
|
/// </summary>
|
||||||
|
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => NullScope.Instance;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ILogger.IsEnabled - Checks if the specified Microsoft log level is enabled.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEnabled(MsLogLevel logLevel)
|
||||||
|
{
|
||||||
|
var acLogLevel = MapFromMsLogLevel(logLevel);
|
||||||
|
return LogLevel <= acLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ILogger.Log - Main logging method called by Microsoft services.
|
||||||
|
/// </summary>
|
||||||
|
public void Log<TState>(MsLogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
|
||||||
|
{
|
||||||
|
if (!IsEnabled(logLevel))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var message = formatter(state, exception);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(message) && exception == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var fullMessage = eventId.Id != 0
|
||||||
|
? $"[{eventId.Id}:{eventId.Name}] {message}"
|
||||||
|
: message;
|
||||||
|
|
||||||
|
var category = ShortenCategoryNames ? GetShortCategoryName(CategoryName) : CategoryName;
|
||||||
|
|
||||||
|
switch (logLevel)
|
||||||
|
{
|
||||||
|
case MsLogLevel.Trace:
|
||||||
|
Detail(fullMessage, category);
|
||||||
|
break;
|
||||||
|
case MsLogLevel.Debug:
|
||||||
|
Debug(fullMessage, category);
|
||||||
|
break;
|
||||||
|
case MsLogLevel.Information:
|
||||||
|
Info(fullMessage, category);
|
||||||
|
break;
|
||||||
|
case MsLogLevel.Warning:
|
||||||
|
Warning(fullMessage, category);
|
||||||
|
break;
|
||||||
|
case MsLogLevel.Error:
|
||||||
|
Error(fullMessage, exception, category);
|
||||||
|
break;
|
||||||
|
case MsLogLevel.Critical:
|
||||||
|
Error($"[CRITICAL] {fullMessage}", exception, category);
|
||||||
|
break;
|
||||||
|
case MsLogLevel.None:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shortens a fully qualified type name to just the class name.
|
||||||
|
/// E.g., "Microsoft.AspNetCore.SignalR.HubConnectionHandler" -> "HubConnectionHandler"
|
||||||
|
/// </summary>
|
||||||
|
private static string? GetShortCategoryName(string? categoryName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(categoryName))
|
||||||
|
return categoryName;
|
||||||
|
|
||||||
|
var lastDot = categoryName.LastIndexOf('.');
|
||||||
|
return lastDot >= 0 ? categoryName[(lastDot + 1)..] : categoryName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps Microsoft.Extensions.Logging.LogLevel to AyCode.Core.Loggers.LogLevel.
|
||||||
|
/// </summary>
|
||||||
|
private static AcLogLevel MapFromMsLogLevel(MsLogLevel msLogLevel)
|
||||||
|
{
|
||||||
|
return msLogLevel switch
|
||||||
|
{
|
||||||
|
MsLogLevel.Trace => AcLogLevel.Detail,
|
||||||
|
MsLogLevel.Debug => AcLogLevel.Debug,
|
||||||
|
MsLogLevel.Information => AcLogLevel.Info,
|
||||||
|
MsLogLevel.Warning => AcLogLevel.Warning,
|
||||||
|
MsLogLevel.Error => AcLogLevel.Error,
|
||||||
|
MsLogLevel.Critical => AcLogLevel.Error,
|
||||||
|
MsLogLevel.None => AcLogLevel.Disabled,
|
||||||
|
_ => AcLogLevel.Info
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// No-op scope implementation for ILogger.BeginScope.
|
||||||
|
/// </summary>
|
||||||
|
private sealed class NullScope : IDisposable
|
||||||
|
{
|
||||||
|
public static NullScope Instance { get; } = new();
|
||||||
|
private NullScope() { }
|
||||||
|
public void Dispose() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
namespace AyCode.Core.Loggers;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
public interface IAcLoggerBase : IAcLogWriterBase
|
namespace AyCode.Core.Loggers;
|
||||||
|
|
||||||
|
public interface IAcLoggerBase : IAcLogWriterBase, ILogger
|
||||||
{
|
{
|
||||||
public List<IAcLogWriterBase> GetWriters { get; }
|
public List<IAcLogWriterBase> GetWriters { get; }
|
||||||
public TLogWriter? Writer<TLogWriter>() where TLogWriter : IAcLogWriterBase;
|
public TLogWriter? Writer<TLogWriter>() where TLogWriter : IAcLogWriterBase;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue