Skip to content

Instantly share code, notes, and snippets.

@graealex
Created March 23, 2023 15:28
Show Gist options
  • Save graealex/43f5667c33df8e33bf60981887b49448 to your computer and use it in GitHub Desktop.
Save graealex/43f5667c33df8e33bf60981887b49448 to your computer and use it in GitHub Desktop.
NLogSink for Avalonia
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