diff --git a/src/Avalonia.Logging.Serilog/SerilogExtensions.cs b/src/Avalonia.Logging.Serilog/SerilogExtensions.cs index 7382421dc6..2ce38769da 100644 --- a/src/Avalonia.Logging.Serilog/SerilogExtensions.cs +++ b/src/Avalonia.Logging.Serilog/SerilogExtensions.cs @@ -1,5 +1,8 @@ -using Avalonia.Controls; +using System; +using Avalonia.Controls; using Serilog; +using Serilog.Configuration; +using Serilog.Filters; using SerilogLevel = Serilog.Events.LogEventLevel; namespace Avalonia.Logging.Serilog @@ -9,21 +12,67 @@ namespace Avalonia.Logging.Serilog /// public static class SerilogExtensions { + private const string DefaultTemplate = "[{Area}] {Message} ({SourceType} #{SourceHash})"; + + /// + /// Logs Avalonia events to the sink. + /// + /// The application class type. + /// The app builder instance. + /// The minimum level to log. + /// The app builder instance. + public static T LogToDebug( + this T builder, + LogEventLevel level = LogEventLevel.Warning) + where T : AppBuilderBase, new() + { + SerilogLogger.Initialize(new LoggerConfiguration() + .MinimumLevel.Is((SerilogLevel)level) + .Enrich.FromLogContext() + .WriteTo.Debug(outputTemplate: DefaultTemplate) + .CreateLogger()); + return builder; + } + /// /// Logs Avalonia events to the sink. /// /// The application class type. /// The app builder instance. + /// The area to log. Valid values are listed in . /// The minimum level to log. /// The app builder instance. public static T LogToDebug( + this T builder, + string area, + LogEventLevel level = LogEventLevel.Warning) + where T : AppBuilderBase, new() + { + SerilogLogger.Initialize(new LoggerConfiguration() + .MinimumLevel.Is((SerilogLevel)level) + .Filter.ByIncludingOnly(Matching.WithProperty("Area", area)) + .Enrich.FromLogContext() + .WriteTo.Debug(outputTemplate: DefaultTemplate) + .CreateLogger()); + return builder; + } + + /// + /// Logs Avalonia events to the sink. + /// + /// The application class type. + /// The app builder instance. + /// The minimum level to log. + /// The app builder instance. + public static T LogToTrace( this T builder, LogEventLevel level = LogEventLevel.Warning) where T : AppBuilderBase, new() { SerilogLogger.Initialize(new LoggerConfiguration() .MinimumLevel.Is((SerilogLevel)level) - .WriteTo.Debug(outputTemplate: "{Area}: {Message}") + .Enrich.FromLogContext() + .WriteTo.Trace(outputTemplate: DefaultTemplate) .CreateLogger()); return builder; } @@ -33,16 +82,20 @@ namespace Avalonia.Logging.Serilog /// /// The application class type. /// The app builder instance. + /// The area to log. Valid values are listed in . /// The minimum level to log. /// The app builder instance. public static T LogToTrace( this T builder, + string area, LogEventLevel level = LogEventLevel.Warning) where T : AppBuilderBase, new() { SerilogLogger.Initialize(new LoggerConfiguration() .MinimumLevel.Is((SerilogLevel)level) - .WriteTo.Trace(outputTemplate: "{Area}: {Message}") + .Filter.ByIncludingOnly(Matching.WithProperty("Area", area)) + .Enrich.FromLogContext() + .WriteTo.Trace(outputTemplate: DefaultTemplate) .CreateLogger()); return builder; } diff --git a/src/Avalonia.Logging.Serilog/SerilogLogger.cs b/src/Avalonia.Logging.Serilog/SerilogLogger.cs index 99145d49e4..0534fe3012 100644 --- a/src/Avalonia.Logging.Serilog/SerilogLogger.cs +++ b/src/Avalonia.Logging.Serilog/SerilogLogger.cs @@ -1,8 +1,9 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. -using System.Collections.Generic; +using System; using Serilog; +using Serilog.Context; using AvaloniaLogEventLevel = Avalonia.Logging.LogEventLevel; using SerilogLogEventLevel = Serilog.Events.LogEventLevel; @@ -14,7 +15,6 @@ namespace Avalonia.Logging.Serilog public class SerilogLogger : ILogSink { private readonly ILogger _output; - private readonly Dictionary _areas = new Dictionary(); /// /// Initializes a new instance of the class. @@ -36,21 +36,21 @@ namespace Avalonia.Logging.Serilog /// public void Log( - AvaloniaLogEventLevel level, - string area, - object source, - string messageTemplate, + AvaloniaLogEventLevel level, + string area, + object source, + string messageTemplate, params object[] propertyValues) { - ILogger areaLogger; + Contract.Requires(area != null); + Contract.Requires(messageTemplate != null); - if (!_areas.TryGetValue(area, out areaLogger)) + using (LogContext.PushProperty("Area", area)) + using (LogContext.PushProperty("SourceType", source?.GetType())) + using (LogContext.PushProperty("SourceHash", source?.GetHashCode())) { - areaLogger = _output.ForContext("Area", area); - _areas.Add(area, areaLogger); + _output.Write((SerilogLogEventLevel)level, messageTemplate, propertyValues); } - - areaLogger.Write((SerilogLogEventLevel)level, messageTemplate, propertyValues); } } }