diff --git a/src/Artemis.UI/ArtemisBootstrapper.cs b/src/Artemis.UI/ArtemisBootstrapper.cs index dbed7a0f4..fda2661ae 100644 --- a/src/Artemis.UI/ArtemisBootstrapper.cs +++ b/src/Artemis.UI/ArtemisBootstrapper.cs @@ -16,6 +16,7 @@ using Artemis.WebClient.Workshop.DryIoc; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Logging; using Avalonia.Styling; using DryIoc; using ReactiveUI; @@ -32,9 +33,9 @@ public static class ArtemisBootstrapper { if (_application != null || _container != null) throw new ArtemisUIException("UI already bootstrapped"); - + Utilities.PrepareFirstLaunch(); - + application.RequestedThemeVariant = ThemeVariant.Dark; _application = application; _container = new Container(rules => rules @@ -51,6 +52,8 @@ public static class ArtemisBootstrapper configureServices?.Invoke(_container); _container.UseDryIocDependencyResolver(); + + Logger.Sink = _container.Resolve(); return _container; } diff --git a/src/Artemis.UI/SerilogAvaloniaSink.cs b/src/Artemis.UI/SerilogAvaloniaSink.cs new file mode 100644 index 000000000..d47382bf2 --- /dev/null +++ b/src/Artemis.UI/SerilogAvaloniaSink.cs @@ -0,0 +1,56 @@ +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using Avalonia.Logging; +using Serilog; +using AvaloniaLogLevel = Avalonia.Logging.LogEventLevel; +using SerilogLogLevel = Serilog.Events.LogEventLevel; + +namespace Artemis.UI; + +[SuppressMessage("ReSharper", "TemplateIsNotCompileTimeConstantProblem")] +public class SerilogAvaloniaSink : ILogSink +{ + private readonly ILogger _logger; + + public SerilogAvaloniaSink(ILogger logger) + { + _logger = logger; + } + + /// + public bool IsEnabled(AvaloniaLogLevel level, string area) + { + SerilogLogLevel logLevel = GetSerilogLogLevel(level, area); + + // Except with binding errors, ignore anything that is information or lower + return (area == "Binding" || logLevel > SerilogLogLevel.Information) && _logger.IsEnabled(logLevel); + } + + /// + public void Log(AvaloniaLogLevel level, string area, object? source, string messageTemplate) + { + SerilogLogLevel logLevel = GetSerilogLogLevel(level, area); + + ILogger logger = source != null ? _logger.ForContext(source.GetType()) : _logger; + logger.Write(logLevel, messageTemplate); + } + + /// + public void Log(AvaloniaLogLevel level, string area, object? source, string messageTemplate, params object?[] propertyValues) + { + SerilogLogLevel logLevel = GetSerilogLogLevel(level, area); + + ILogger logger = source != null ? _logger.ForContext(source.GetType()) : _logger; + logger.Write(logLevel, messageTemplate, propertyValues); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static SerilogLogLevel GetSerilogLogLevel(AvaloniaLogLevel level, string area) + { + // Avalonia considers binding errors warnings, we'll treat them Verbose as to not spam people's logs + // And yes we should fix them instead but we can't always: https://github.com/AvaloniaUI/Avalonia/issues/5762 + if (area == "Binding") + return SerilogLogLevel.Verbose; + return (SerilogLogLevel) level; + } +} \ No newline at end of file diff --git a/src/Artemis.sln.DotSettings b/src/Artemis.sln.DotSettings index 6943df083..289ea3eae 100644 --- a/src/Artemis.sln.DotSettings +++ b/src/Artemis.sln.DotSettings @@ -243,6 +243,7 @@ True True True + True True True True