From fd4991116fd5c413e16a541af9fb43d9c6929228 Mon Sep 17 00:00:00 2001 From: George Drak Date: Wed, 22 Mar 2023 12:46:30 +0500 Subject: [PATCH] feat(serilog): use configuration to change serilog settings --- .../Pages/Logging.razor | 78 ++++++++++++++++--- .../Pages/Logging.razor | 72 +++++++++++++++-- src/Directory.Packages.props | 1 - src/Sitko.Core.App/Application.cs | 4 +- src/Sitko.Core.App/HostedApplication.cs | 15 ++-- .../Logging/LoggingExtensions.cs | 19 +---- .../SerilogDynamicConfigurationProvider.cs | 36 +++++++++ .../SerilogDynamicConfigurationSource.cs | 8 ++ src/Sitko.Core.App/Sitko.Core.App.csproj | 1 - src/Sitko.Core.Blazor.Wasm/WasmApplication.cs | 6 +- 10 files changed, 192 insertions(+), 48 deletions(-) create mode 100644 src/Sitko.Core.App/Logging/SerilogDynamicConfigurationProvider.cs create mode 100644 src/Sitko.Core.App/Logging/SerilogDynamicConfigurationSource.cs diff --git a/apps/Sitko.Core.Apps.Blazor/Pages/Logging.razor b/apps/Sitko.Core.Apps.Blazor/Pages/Logging.razor index a0d840379..1ddf19ec4 100644 --- a/apps/Sitko.Core.Apps.Blazor/Pages/Logging.razor +++ b/apps/Sitko.Core.Apps.Blazor/Pages/Logging.razor @@ -1,12 +1,72 @@ @page "/Logging" -@using Thinktecture.Extensions.Configuration @using Serilog.Events +@using Microsoft.Extensions.Logging +@using System.Threading +@using Microsoft.Extensions.Configuration +@using Sitko.Core.App.Logging @inherits BaseComponent -@inject ISerilogConfiguration loggingConfiguration - - - - - - - + + Set debug + Set info + Set warning + Set error + Reset + + @if (!string.IsNullOrEmpty(debugView)) + { +
+@debugView
+
+ } +
+ +@code +{ + private Task? logTask; + private readonly CancellationTokenSource cts = new(); + private string? debugView; + + protected override void Initialize() + { + base.Initialize(); + logTask = StartLoggingAsync(); + } + + private async Task StartLoggingAsync() + { + while (!cts.IsCancellationRequested) + { + await Task.Delay(5000); + Logger.LogDebug("Debug"); + Logger.LogInformation("Info"); + Logger.LogWarning("Warning"); + Logger.LogError("Error"); + } + } + + protected override async Task DisposeAsync(bool disposing) + { + await base.DisposeAsync(disposing); + if (logTask is not null) + { + cts.Cancel(); + await logTask; + } + } + + private Task SetLevel(LogEventLevel level) + { + SerilogDynamicConfigurationProvider.Instance.SetLevel(level); + var root = (IConfigurationRoot)GetRequiredService(); + debugView = root.GetDebugView(); + return Task.CompletedTask; + } + + private Task ResetLevel() + { + SerilogDynamicConfigurationProvider.Instance.ResetLevel(); + var root = (IConfigurationRoot)GetRequiredService(); + debugView = root.GetDebugView(); + return Task.CompletedTask; + } +} diff --git a/apps/Sitko.Core.Apps.MudBlazorDemo/Pages/Logging.razor b/apps/Sitko.Core.Apps.MudBlazorDemo/Pages/Logging.razor index 35e819886..1ddf19ec4 100644 --- a/apps/Sitko.Core.Apps.MudBlazorDemo/Pages/Logging.razor +++ b/apps/Sitko.Core.Apps.MudBlazorDemo/Pages/Logging.razor @@ -1,10 +1,72 @@ @page "/Logging" -@using Thinktecture.Extensions.Configuration @using Serilog.Events +@using Microsoft.Extensions.Logging +@using System.Threading +@using Microsoft.Extensions.Configuration +@using Sitko.Core.App.Logging @inherits BaseComponent -@inject ISerilogConfiguration LoggingConfiguration - Set debug - Set info - Reset + Set debug + Set info + Set warning + Set error + Reset + + @if (!string.IsNullOrEmpty(debugView)) + { +
+@debugView
+
+ }
+ +@code +{ + private Task? logTask; + private readonly CancellationTokenSource cts = new(); + private string? debugView; + + protected override void Initialize() + { + base.Initialize(); + logTask = StartLoggingAsync(); + } + + private async Task StartLoggingAsync() + { + while (!cts.IsCancellationRequested) + { + await Task.Delay(5000); + Logger.LogDebug("Debug"); + Logger.LogInformation("Info"); + Logger.LogWarning("Warning"); + Logger.LogError("Error"); + } + } + + protected override async Task DisposeAsync(bool disposing) + { + await base.DisposeAsync(disposing); + if (logTask is not null) + { + cts.Cancel(); + await logTask; + } + } + + private Task SetLevel(LogEventLevel level) + { + SerilogDynamicConfigurationProvider.Instance.SetLevel(level); + var root = (IConfigurationRoot)GetRequiredService(); + debugView = root.GetDebugView(); + return Task.CompletedTask; + } + + private Task ResetLevel() + { + SerilogDynamicConfigurationProvider.Instance.ResetLevel(); + var root = (IConfigurationRoot)GetRequiredService(); + debugView = root.GetDebugView(); + return Task.CompletedTask; + } +} diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index e1cdf8844..273c63918 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -110,7 +110,6 @@ - diff --git a/src/Sitko.Core.App/Application.cs b/src/Sitko.Core.App/Application.cs index eefaefcd3..28a6e40b5 100644 --- a/src/Sitko.Core.App/Application.cs +++ b/src/Sitko.Core.App/Application.cs @@ -7,6 +7,7 @@ using Serilog; using Serilog.Events; using Sitko.Core.App.Localization; +using Sitko.Core.App.Logging; using Sitko.FluentValidation; using Tempus; @@ -119,6 +120,8 @@ protected void ConfigureConfiguration(IApplicationContext appContext, IConfigura { moduleRegistration.ConfigureAppConfiguration(appContext, builder); } + + builder.Add(new SerilogDynamicConfigurationSource()); } protected virtual LoggerConfiguration ConfigureLogging(IApplicationContext applicationContext, @@ -450,4 +453,3 @@ public Application AddModule( configureOptions?.Invoke(moduleOptions); }, optionsKey); } - diff --git a/src/Sitko.Core.App/HostedApplication.cs b/src/Sitko.Core.App/HostedApplication.cs index 09f0263cd..3a84547cd 100644 --- a/src/Sitko.Core.App/HostedApplication.cs +++ b/src/Sitko.Core.App/HostedApplication.cs @@ -10,7 +10,6 @@ using Serilog.Extensions.Logging; using Sitko.Core.App.Helpers; using Sitko.Core.App.Logging; -using Thinktecture.Extensions.Configuration; namespace Sitko.Core.App; @@ -101,7 +100,6 @@ protected IHostBuilder ConfigureHostBuilder(Action? configure = nu InitApplication(); LogInternal("Create main host builder"); - var serilogConfiguration = new SerilogConfiguration(); var hostBuilder = CreateHostBuilder(Args) .UseDefaultServiceProvider(options => { @@ -127,27 +125,27 @@ protected IHostBuilder ConfigureHostBuilder(Action? configure = nu hostBuilder.ConfigureAppConfiguration((_, builder) => { ConfigureConfiguration(bootApplicationContext, builder); - LoggingExtensions.ConfigureSerilogConfiguration(builder, serilogConfiguration); }) .ConfigureServices((_, services) => { RegisterApplicationServices(bootApplicationContext, services); services.AddHostedService(); - }).ConfigureLogging((_, builder) => + }).ConfigureLogging((builderContext, builder) => { LogInternal("Configure logging"); - LoggingExtensions.ConfigureSerilog(bootApplicationContext, builder, serilogConfiguration, + var runtimeContext = GetContext(builderContext.HostingEnvironment, builderContext.Configuration); + LoggingExtensions.ConfigureSerilog(runtimeContext, builder, configuration => { configuration = configuration.Enrich.WithMachineName(); - if (bootApplicationContext.Options.EnableConsoleLogging == true) + if (runtimeContext.Options.EnableConsoleLogging == true) { configuration = configuration.WriteTo.Console( - outputTemplate: bootApplicationContext.Options.ConsoleLogFormat, + outputTemplate: runtimeContext.Options.ConsoleLogFormat, formatProvider: CultureInfo.InvariantCulture); } - return ConfigureLogging(bootApplicationContext, configuration); + return ConfigureLogging(runtimeContext, configuration); }); }); configure?.Invoke(hostBuilder); @@ -253,4 +251,3 @@ public HostedApplicationContext(Application application, IConfiguration configur protected override void ConfigureApplicationOptions(ApplicationOptions options) => options.EnableConsoleLogging ??= environment.IsDevelopment(); } - diff --git a/src/Sitko.Core.App/Logging/LoggingExtensions.cs b/src/Sitko.Core.App/Logging/LoggingExtensions.cs index 454718a6c..a9c69ab3d 100644 --- a/src/Sitko.Core.App/Logging/LoggingExtensions.cs +++ b/src/Sitko.Core.App/Logging/LoggingExtensions.cs @@ -1,23 +1,13 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Serilog; -using Thinktecture; -using Thinktecture.Extensions.Configuration; namespace Sitko.Core.App.Logging; public class LoggingExtensions { - public static void ConfigureSerilogConfiguration(IConfigurationBuilder configurationBuilder, - SerilogConfiguration serilogConfiguration) => - configurationBuilder.AddLoggingConfiguration(serilogConfiguration, "Serilog"); - public static void ConfigureSerilog(IApplicationContext appContext, ILoggingBuilder builder, - SerilogConfiguration serilogConfiguration, Func configureLogging) + Func configureLogging) { - builder.Services.AddSingleton(serilogConfiguration); - builder.AddConfiguration(appContext.Configuration.GetSection("Logging")); var loggerConfiguration = new LoggerConfiguration(); loggerConfiguration.ReadFrom.Configuration(appContext.Configuration); loggerConfiguration @@ -25,14 +15,9 @@ public static void ConfigureSerilog(IApplicationContext appContext, ILoggingBuil .Enrich.WithProperty("App", appContext.Name) .Enrich.WithProperty("AppVersion", appContext.Version) .Enrich.WithProperty("AppEnvironment", appContext.Environment); - - loggerConfiguration = configureLogging(loggerConfiguration); - - Log.Logger = loggerConfiguration.CreateLogger(); builder.ClearProviders(); builder.AddSerilog(); } } - diff --git a/src/Sitko.Core.App/Logging/SerilogDynamicConfigurationProvider.cs b/src/Sitko.Core.App/Logging/SerilogDynamicConfigurationProvider.cs new file mode 100644 index 000000000..25d610f4b --- /dev/null +++ b/src/Sitko.Core.App/Logging/SerilogDynamicConfigurationProvider.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Configuration; +using Serilog.Events; + +namespace Sitko.Core.App.Logging; + +public class SerilogDynamicConfigurationProvider : ConfigurationProvider +{ + private const string DefaultCategory = "Default"; + public static readonly SerilogDynamicConfigurationProvider Instance = new(); + + public void SetLevel(LogEventLevel level, string? category = null) + { + category ??= DefaultCategory; + Set(GetKey(category), level.ToString()); + OnReload(); + } + + private static string GetKey(string category) + { + var key = "Serilog:MinimumLevel:"; + if (category != DefaultCategory) + { + key += "Override:"; + } + + key += category; + return key; + } + + public void ResetLevel(string? category = null) + { + category ??= DefaultCategory; + Set(GetKey(category), null); + OnReload(); + } +} diff --git a/src/Sitko.Core.App/Logging/SerilogDynamicConfigurationSource.cs b/src/Sitko.Core.App/Logging/SerilogDynamicConfigurationSource.cs new file mode 100644 index 000000000..00b72712e --- /dev/null +++ b/src/Sitko.Core.App/Logging/SerilogDynamicConfigurationSource.cs @@ -0,0 +1,8 @@ +using Microsoft.Extensions.Configuration; + +namespace Sitko.Core.App.Logging; + +public class SerilogDynamicConfigurationSource : IConfigurationSource +{ + public IConfigurationProvider Build(IConfigurationBuilder builder) => SerilogDynamicConfigurationProvider.Instance; +} diff --git a/src/Sitko.Core.App/Sitko.Core.App.csproj b/src/Sitko.Core.App/Sitko.Core.App.csproj index cec13a55a..0eebe7c2f 100644 --- a/src/Sitko.Core.App/Sitko.Core.App.csproj +++ b/src/Sitko.Core.App/Sitko.Core.App.csproj @@ -12,7 +12,6 @@ - diff --git a/src/Sitko.Core.Blazor.Wasm/WasmApplication.cs b/src/Sitko.Core.Blazor.Wasm/WasmApplication.cs index bd00d98e0..0ca09c30d 100644 --- a/src/Sitko.Core.Blazor.Wasm/WasmApplication.cs +++ b/src/Sitko.Core.Blazor.Wasm/WasmApplication.cs @@ -11,7 +11,6 @@ using Sitko.Core.App.Logging; using Sitko.Core.Blazor.Components; using Sitko.Core.Blazor.Forms; -using Thinktecture.Extensions.Configuration; namespace Sitko.Core.Blazor.Wasm; @@ -76,9 +75,7 @@ private WebAssemblyHostBuilder ConfigureHostBuilder(Action { configuration = configuration.WriteTo.BrowserConsole( @@ -150,4 +147,3 @@ protected override IApplicationContext GetContext(IServiceProvider serviceProvid serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService()); } -