日志配置不适用于Avalonia Android中的NLog 5

zd287kbt  于 2023-06-20  发布在  Android
关注(0)|答案(1)|浏览(195)

最近我更新NLog版本从4到5,我现在有一个问题。
最初我把我的NLog.config放在asset文件夹中,NLog会自动扫描并加载它。
但是在我升级到5并遵循document的方式之后,它就不再工作了。
我将NLog.config设置为嵌入式资源,并在OnCreate()中调用LogManager.Setup().LoadConfigurationFromAssemblyResource(typeof(MainActivity).GetTypeInfo().Assembly);
如何使其正确工作?

mrphzbgm

mrphzbgm1#

您可以从嵌入式资源加载NLog配置:

LogManager.Setup().LoadConfigurationFromAssemblyResource(typeof(MainActivity).GetTypeInfo().Assembly);

您也可以通过为NLog注册ILogSink将Avalonia日志输出重定向到NLog:

using Avalonia.Logging;
using NLog;

namespace Logging
{
    public class NLogSink : ILogSink
    {
        private readonly LogEventLevel _level;
        private readonly HashSet<string>? _areas;

        public NLogSink(
            LogEventLevel minimumLevel,
            IList<string>? areas = null)
        {
            _level = minimumLevel;
            _areas = areas?.Count > 0 ? new HashSet<string(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))
            {
                Nvar logger = Resolve(source?.GetType(), area);
                logger.Log(LogLevelToNLogLevel(level), messageTemplate, propertyValues);
            }
        }

        public void Log(LogEventLevel level, string area, object? source, string messageTemplate, params object?[] propertyValues)
        {
            if (IsEnabled(level, area))
            {
                var logger = Resolve(source?.GetType(), area);
                logger.Log(LogLevelToNLogLevel(level), messageTemplate, propertyValues);
            }
        }

        private ConcurrentDictionary<string, NLog.Logger> _loggerCache = new ConcurrentDictionary<string, NLog.Logger>();

        public static NLog.ILogger Resolve(Type? source, string? area)
        {
           var loggerName = source?.ToString() ?? area;
           if (string.IsNullOrEmpty(loggerName))
               loggerName = typeof(NLogSink).ToString();

           if (!_loggerCache.TryGetValue(loggerName, out var logger))
           {
              logger = NLog.LogManager.GetLogger(loggerName);
              _loggerCache.TryAdd(loggerName, logger);
           }
           return logger;
        }

        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;
        }
    }
}

然后像这样设置:

public static AppBuilder BuildAvaloniaApp()
    => AppBuilder.Configure<App>()
        .UsePlatformDetect()
        .LogToNLog();

标签:https://gist.github.com/graealex/43f5667c33df8e33bf60981887b49448
标签:https://docs.avaloniaui.net/docs/getting-started/logging-errors-and-warnings

相关问题