Created
March 23, 2023 15:28
-
-
Save graealex/43f5667c33df8e33bf60981887b49448 to your computer and use it in GitHub Desktop.
NLogSink for Avalonia
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Avalonia.Logging; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using NLog; | |
using Splat; | |
using NLog.Fluent; | |
using DynamicData.Binding; | |
namespace Logging | |
{ | |
public class NLogSink : ILogSink | |
{ | |
private readonly LogEventLevel _level; | |
private readonly IList<string>? _areas; | |
public NLogSink( | |
LogEventLevel minimumLevel, | |
IList<string>? areas = null) | |
{ | |
_level = minimumLevel; | |
_areas = areas?.Count > 0 ? areas : null; | |
} | |
public bool IsEnabled(LogEventLevel level, string area) | |
{ | |
return level >= _level && (_areas?.Contains(area) ?? true); | |
} | |
public void Log(LogEventLevel level, string area, object? source, string messageTemplate) | |
{ | |
if (IsEnabled(level, area)) | |
{ | |
NLog.ILogger? logger = null; | |
if (source is not null) | |
logger = Resolve(source.GetType()); | |
else | |
logger = Resolve(typeof(NLogSink)); | |
logger.Log(LogLevelToNLogLevel(level), $"{area}: {messageTemplate}"); | |
} | |
} | |
public void Log(LogEventLevel level, string area, object? source, string messageTemplate, params object?[] propertyValues) | |
{ | |
if (IsEnabled(level, area)) | |
{ | |
NLog.ILogger? logger = null; | |
if (source is not null) | |
logger = Resolve(source.GetType()); | |
else | |
logger = Resolve(typeof(NLogSink)); | |
logger.Log(LogLevelToNLogLevel(level), $"{area}: {messageTemplate}", propertyValues); | |
} | |
} | |
private const int MaxCacheSize = 16; | |
private static readonly MemoizingMRUCache<Type, NLog.ILogger> _loggerCache = new( | |
(type, _) => LogManager.GetLogger(type.ToString()), | |
MaxCacheSize); | |
public static NLog.ILogger Resolve(Type type) => _loggerCache.Get(type, null); | |
private static NLog.LogLevel LogLevelToNLogLevel(LogEventLevel level) | |
{ | |
switch (level) | |
{ | |
case LogEventLevel.Verbose: | |
return NLog.LogLevel.Trace; | |
case LogEventLevel.Debug: | |
return NLog.LogLevel.Debug; | |
case LogEventLevel.Information: | |
return NLog.LogLevel.Info; | |
case LogEventLevel.Warning: | |
return NLog.LogLevel.Warn; | |
case LogEventLevel.Error: | |
return NLog.LogLevel.Error; | |
case LogEventLevel.Fatal: | |
return NLog.LogLevel.Fatal; | |
default: | |
return NLog.LogLevel.Trace; | |
} | |
} | |
} | |
public static class NLogSinkExtensions | |
{ | |
public static AppBuilder LogToNLog( | |
this AppBuilder builder, | |
LogEventLevel level = LogEventLevel.Warning, | |
params string[] areas) | |
{ | |
Logger.Sink = new NLogSink(level, areas); | |
return builder; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment