From c308d765704778925b825f4459924f7b2d48a113 Mon Sep 17 00:00:00 2001 From: Adam Chester Date: Fri, 2 Aug 2019 10:15:51 +1000 Subject: [PATCH 1/7] Configurable sync root for console sink, enabling scenarios where the application needs to sync with the console, or the application wants to keep multiple console sinks which do not need to be sync'd. --- sample/ConsoleDemo/Program.cs | 54 ++++++++++++++++++- .../ConsoleLoggerConfigurationExtensions.cs | 16 ++++-- .../Sinks/SystemConsole/ConsoleSink.cs | 13 ++++- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/sample/ConsoleDemo/Program.cs b/sample/ConsoleDemo/Program.cs index 28ce01f..18ce5b8 100644 --- a/sample/ConsoleDemo/Program.cs +++ b/sample/ConsoleDemo/Program.cs @@ -1,13 +1,63 @@ using Serilog; using Serilog.Sinks.SystemConsole.Themes; using System; +using System.Linq; using System.Threading; +using System.Threading.Tasks; namespace ConsoleDemo { public class Program { - public static void Main() + public static void Main(string[] args) + { + if (args != null && args.Length == 1) + { + switch (args[0]) + { + case "--sync-root-default": + SystemConsoleSyncTest(syncRootForLogger1: null, syncRootForLogger2: null); + return; + case "--sync-root-separate": + SystemConsoleSyncTest(syncRootForLogger1: new object(), syncRootForLogger2: new object()); + return; + case "--sync-root-same": + { + var sameSyncRoot = new object(); + SystemConsoleSyncTest(syncRootForLogger1: sameSyncRoot, syncRootForLogger2: sameSyncRoot); + return; + } + } + } + + AnsiConsoleThemeTest(); + } + + static void SystemConsoleSyncTest(object syncRootForLogger1, object syncRootForLogger2) + { + var logger1 = new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("Logger", "logger1") + .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger1) + .CreateLogger(); + + var logger2 = new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("Logger", "logger2") + .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger2) + .CreateLogger(); + + var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; + System.Threading.Tasks.Parallel.For(0, 1000, options, (i, loopState) => + { + var logger = (i % 2 == 0) ? logger1 : logger2; + logger.Information("Event {Iteration} generated by {ThreadId}", i, Thread.CurrentThread.ManagedThreadId); + }); + + Log.CloseAndFlush(); + } + + static void AnsiConsoleThemeTest() { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() @@ -29,7 +79,7 @@ public static void Main() Log.Error(e, "Something went wrong"); } - Log.CloseAndFlush(); + Log.CloseAndFlush(); } static void Fail() diff --git a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs index 7c0b7f1..3b83d75 100644 --- a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs @@ -38,6 +38,9 @@ public static class ConsoleLoggerConfigurationExtensions /// events passed through the sink. Ignored when is specified. /// A message template describing the format used to write to the sink. /// The default is "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}". + /// An object that will be used to `lock` (sync) access to the console output. If you specify this, you + /// will have the ability to lock on this object, and guarantee that the console sink will not be about to output anything while + /// the lock is held. /// Supplies culture-specific formatting information, or null. /// A switch allowing the pass-through minimum level /// to be changed at runtime. @@ -52,7 +55,8 @@ public static LoggerConfiguration Console( IFormatProvider formatProvider = null, LoggingLevelSwitch levelSwitch = null, LogEventLevel? standardErrorFromLevel = null, - ConsoleTheme theme = null) + ConsoleTheme theme = null, + object syncRoot = null) { if (sinkConfiguration == null) throw new ArgumentNullException(nameof(sinkConfiguration)); if (outputTemplate == null) throw new ArgumentNullException(nameof(outputTemplate)); @@ -62,7 +66,7 @@ public static LoggerConfiguration Console( theme ?? SystemConsoleThemes.Literate; var formatter = new OutputTemplateRenderer(appliedTheme, outputTemplate, formatProvider); - return sinkConfiguration.Sink(new ConsoleSink(appliedTheme, formatter, standardErrorFromLevel), restrictedToMinimumLevel, levelSwitch); + return sinkConfiguration.Sink(new ConsoleSink(appliedTheme, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); } /// @@ -71,6 +75,9 @@ public static LoggerConfiguration Console( /// Logger sink configuration. /// Controls the rendering of log events into text, for example to log JSON. To /// control plain text formatting, use the overload that accepts an output template. + /// An object that will be used to `lock` (sync) access to the console output. If you specify this, you + /// will have the ability to lock on this object, and guarantee that the console sink will not be about to output anything while + /// the lock is held. /// The minimum level for /// events passed through the sink. Ignored when is specified. /// A switch allowing the pass-through minimum level @@ -82,12 +89,13 @@ public static LoggerConfiguration Console( ITextFormatter formatter, LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, LoggingLevelSwitch levelSwitch = null, - LogEventLevel? standardErrorFromLevel = null) + LogEventLevel? standardErrorFromLevel = null, + object syncRoot = null) { if (sinkConfiguration == null) throw new ArgumentNullException(nameof(sinkConfiguration)); if (formatter == null) throw new ArgumentNullException(nameof(formatter)); - return sinkConfiguration.Sink(new ConsoleSink(ConsoleTheme.None, formatter, standardErrorFromLevel), restrictedToMinimumLevel, levelSwitch); + return sinkConfiguration.Sink(new ConsoleSink(ConsoleTheme.None, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); } } } diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs index 3116448..0c899c4 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs @@ -28,7 +28,8 @@ class ConsoleSink : ILogEventSink readonly LogEventLevel? _standardErrorFromLevel; readonly ConsoleTheme _theme; readonly ITextFormatter _formatter; - static readonly object _syncRoot = new object(); + readonly object _syncRoot; + static readonly object _defaultSyncRoot = new object(); const int DefaultWriteBufferCapacity = 256; @@ -41,10 +42,20 @@ public ConsoleSink( ConsoleTheme theme, ITextFormatter formatter, LogEventLevel? standardErrorFromLevel) + : this(theme, formatter, standardErrorFromLevel, _defaultSyncRoot) + { + } + + public ConsoleSink( + ConsoleTheme theme, + ITextFormatter formatter, + LogEventLevel? standardErrorFromLevel, + object syncRoot) { _standardErrorFromLevel = standardErrorFromLevel; _theme = theme ?? throw new ArgumentNullException(nameof(theme)); _formatter = formatter; + _syncRoot = syncRoot ?? _defaultSyncRoot; } public void Emit(LogEvent logEvent) From 95bbfb692a4bbdf204f372988a6b63fdc1e69eed Mon Sep 17 00:00:00 2001 From: Adam Chester Date: Fri, 2 Aug 2019 10:27:56 +1000 Subject: [PATCH 2/7] Fix accidental spaces --- sample/ConsoleDemo/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/ConsoleDemo/Program.cs b/sample/ConsoleDemo/Program.cs index 18ce5b8..9f2d3c1 100644 --- a/sample/ConsoleDemo/Program.cs +++ b/sample/ConsoleDemo/Program.cs @@ -79,7 +79,7 @@ static void AnsiConsoleThemeTest() Log.Error(e, "Something went wrong"); } - Log.CloseAndFlush(); + Log.CloseAndFlush(); } static void Fail() From d12536dc5b286e7ca131e57cd96a624874f9e234 Mon Sep 17 00:00:00 2001 From: Adam Chester Date: Thu, 15 Aug 2019 15:34:04 +1000 Subject: [PATCH 3/7] revert sample changes --- sample/ConsoleDemo/Program.cs | 48 ----------------------------------- 1 file changed, 48 deletions(-) diff --git a/sample/ConsoleDemo/Program.cs b/sample/ConsoleDemo/Program.cs index 9f2d3c1..2ea3259 100644 --- a/sample/ConsoleDemo/Program.cs +++ b/sample/ConsoleDemo/Program.cs @@ -10,54 +10,6 @@ namespace ConsoleDemo public class Program { public static void Main(string[] args) - { - if (args != null && args.Length == 1) - { - switch (args[0]) - { - case "--sync-root-default": - SystemConsoleSyncTest(syncRootForLogger1: null, syncRootForLogger2: null); - return; - case "--sync-root-separate": - SystemConsoleSyncTest(syncRootForLogger1: new object(), syncRootForLogger2: new object()); - return; - case "--sync-root-same": - { - var sameSyncRoot = new object(); - SystemConsoleSyncTest(syncRootForLogger1: sameSyncRoot, syncRootForLogger2: sameSyncRoot); - return; - } - } - } - - AnsiConsoleThemeTest(); - } - - static void SystemConsoleSyncTest(object syncRootForLogger1, object syncRootForLogger2) - { - var logger1 = new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("Logger", "logger1") - .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger1) - .CreateLogger(); - - var logger2 = new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("Logger", "logger2") - .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger2) - .CreateLogger(); - - var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; - System.Threading.Tasks.Parallel.For(0, 1000, options, (i, loopState) => - { - var logger = (i % 2 == 0) ? logger1 : logger2; - logger.Information("Event {Iteration} generated by {ThreadId}", i, Thread.CurrentThread.ManagedThreadId); - }); - - Log.CloseAndFlush(); - } - - static void AnsiConsoleThemeTest() { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() From dbd80a725320b70443aa2100462a31d678775bc8 Mon Sep 17 00:00:00 2001 From: Adam Chester Date: Thu, 15 Aug 2019 15:35:12 +1000 Subject: [PATCH 4/7] revert sample changes --- sample/ConsoleDemo/Program.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sample/ConsoleDemo/Program.cs b/sample/ConsoleDemo/Program.cs index 2ea3259..28ce01f 100644 --- a/sample/ConsoleDemo/Program.cs +++ b/sample/ConsoleDemo/Program.cs @@ -1,15 +1,13 @@ using Serilog; using Serilog.Sinks.SystemConsole.Themes; using System; -using System.Linq; using System.Threading; -using System.Threading.Tasks; namespace ConsoleDemo { public class Program { - public static void Main(string[] args) + public static void Main() { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() From 7813ab9427278a187345f2e352694d91f79cc76e Mon Sep 17 00:00:00 2001 From: Adam Chester Date: Thu, 15 Aug 2019 15:38:56 +1000 Subject: [PATCH 5/7] Move default synroot to config extensions --- .../ConsoleLoggerConfigurationExtensions.cs | 4 ++++ .../Sinks/SystemConsole/ConsoleSink.cs | 11 +---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs index 3b83d75..01b085b 100644 --- a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs @@ -28,6 +28,7 @@ namespace Serilog /// public static class ConsoleLoggerConfigurationExtensions { + private static object DefaultSyncRoot = new object(); const string DefaultConsoleOutputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"; /// @@ -65,6 +66,8 @@ public static LoggerConfiguration Console( ConsoleTheme.None : theme ?? SystemConsoleThemes.Literate; + syncRoot = syncRoot ?? DefaultSyncRoot; + var formatter = new OutputTemplateRenderer(appliedTheme, outputTemplate, formatProvider); return sinkConfiguration.Sink(new ConsoleSink(appliedTheme, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); } @@ -95,6 +98,7 @@ public static LoggerConfiguration Console( if (sinkConfiguration == null) throw new ArgumentNullException(nameof(sinkConfiguration)); if (formatter == null) throw new ArgumentNullException(nameof(formatter)); + syncRoot = syncRoot ?? DefaultSyncRoot; return sinkConfiguration.Sink(new ConsoleSink(ConsoleTheme.None, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); } } diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs index 0c899c4..bbe09e0 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs @@ -29,7 +29,6 @@ class ConsoleSink : ILogEventSink readonly ConsoleTheme _theme; readonly ITextFormatter _formatter; readonly object _syncRoot; - static readonly object _defaultSyncRoot = new object(); const int DefaultWriteBufferCapacity = 256; @@ -38,14 +37,6 @@ static ConsoleSink() WindowsConsole.EnableVirtualTerminalProcessing(); } - public ConsoleSink( - ConsoleTheme theme, - ITextFormatter formatter, - LogEventLevel? standardErrorFromLevel) - : this(theme, formatter, standardErrorFromLevel, _defaultSyncRoot) - { - } - public ConsoleSink( ConsoleTheme theme, ITextFormatter formatter, @@ -55,7 +46,7 @@ public ConsoleSink( _standardErrorFromLevel = standardErrorFromLevel; _theme = theme ?? throw new ArgumentNullException(nameof(theme)); _formatter = formatter; - _syncRoot = syncRoot ?? _defaultSyncRoot; + _syncRoot = syncRoot ?? throw new ArgumentNullException(nameof(syncRoot)); } public void Emit(LogEvent logEvent) From ad280ad85b4b2761d9de21808c6f4546298fb942 Mon Sep 17 00:00:00 2001 From: Adam Chester Date: Tue, 20 Aug 2019 14:50:13 +1000 Subject: [PATCH 6/7] Added `SyncWritesDemo` --- Build.ps1 | 25 ++++++--- sample/SyncWritesDemo/Program.cs | 57 +++++++++++++++++++++ sample/SyncWritesDemo/SyncWritesDemo.csproj | 12 +++++ serilog-sinks-console.sln | 7 +++ 4 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 sample/SyncWritesDemo/Program.cs create mode 100644 sample/SyncWritesDemo/SyncWritesDemo.csproj diff --git a/Build.ps1 b/Build.ps1 index ee4117d..7442231 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -1,9 +1,9 @@ -echo "build: Build started" +Write-Host "build: Build started" Push-Location $PSScriptRoot if(Test-Path .\artifacts) { - echo "build: Cleaning .\artifacts" + Write-Host "build: Cleaning .\artifacts" Remove-Item .\artifacts -Force -Recurse } @@ -15,13 +15,13 @@ $suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch $commitHash = $(git rev-parse --short HEAD) $buildSuffix = @{ $true = "$($suffix)-$($commitHash)"; $false = "$($branch)-$($commitHash)" }[$suffix -ne ""] -echo "build: Package version suffix is $suffix" -echo "build: Build version suffix is $buildSuffix" +Write-Host "build: Package version suffix is $suffix" +Write-Host "build: Build version suffix is $buildSuffix" -foreach ($src in ls src/*) { +foreach ($src in Get-ChildItem src/*) { Push-Location $src - echo "build: Packaging project in $src" + Write-Host "build: Packaging project in $src" & dotnet build -c Release --version-suffix=$buildSuffix if ($suffix) { @@ -34,10 +34,21 @@ foreach ($src in ls src/*) { Pop-Location } +foreach ($sample in Get-ChildItem sample/*) { + Push-Location $sample + + Write-Host "build: Testing project in $sample" + + & dotnet build -c Release --version-suffix=$buildSuffix + if($LASTEXITCODE -ne 0) { exit 3 } + + Pop-Location +} + foreach ($test in ls test/*.Tests) { Push-Location $test - echo "build: Testing project in $test" + Write-Host "build: Testing project in $test" & dotnet test -c Release if($LASTEXITCODE -ne 0) { exit 3 } diff --git a/sample/SyncWritesDemo/Program.cs b/sample/SyncWritesDemo/Program.cs new file mode 100644 index 0000000..07713b4 --- /dev/null +++ b/sample/SyncWritesDemo/Program.cs @@ -0,0 +1,57 @@ +using Serilog; +using Serilog.Sinks.SystemConsole.Themes; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SyncWritesDemo +{ + public static class Program + { + public static void Main(string[] args) + { + Console.WriteLine("A sample of how to sync writes to the console sink."); + + if (args != null && args.Length == 1) + { + switch (args[0]) + { + case "--sync-root-default": + SystemConsoleSyncTest(syncRootForLogger1: null, syncRootForLogger2: null); + return; + case "--sync-root-separate": + SystemConsoleSyncTest(syncRootForLogger1: new object(), syncRootForLogger2: new object()); + return; + case "--sync-root-same": + var sameSyncRoot = new object(); + SystemConsoleSyncTest(syncRootForLogger1: sameSyncRoot, syncRootForLogger2: sameSyncRoot); + return; + } + } + + Console.WriteLine("Expecting one of the following arguments:{0}--sync-root-default{0}--sync-root-separate{0}--sync-root-same", Environment.NewLine); + } + + static void SystemConsoleSyncTest(object syncRootForLogger1, object syncRootForLogger2) + { + var logger1 = new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("Logger", "logger1") + .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger1) + .CreateLogger(); + + var logger2 = new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("Logger", "logger2") + .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger2) + .CreateLogger(); + + var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; + System.Threading.Tasks.Parallel.For(0, 1000, options, (i, loopState) => + { + var logger = (i % 2 == 0) ? logger1 : logger2; + logger.Information("Event {Iteration} generated by {ThreadId}", i, Thread.CurrentThread.ManagedThreadId); + }); + } + } +} diff --git a/sample/SyncWritesDemo/SyncWritesDemo.csproj b/sample/SyncWritesDemo/SyncWritesDemo.csproj new file mode 100644 index 0000000..169fe56 --- /dev/null +++ b/sample/SyncWritesDemo/SyncWritesDemo.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.0 + + + + + + + \ No newline at end of file diff --git a/serilog-sinks-console.sln b/serilog-sinks-console.sln index 365f9f9..e223156 100644 --- a/serilog-sinks-console.sln +++ b/serilog-sinks-console.sln @@ -27,6 +27,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{CF8176 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleDemo", "sample\ConsoleDemo\ConsoleDemo.csproj", "{DBF4907A-63A2-4895-8DEF-59F90C20380B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyncWritesDemo", "sample\SyncWritesDemo\SyncWritesDemo.csproj", "{633AE0AD-C9D4-440D-874A-C0F4632DB75F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,6 +47,10 @@ Global {DBF4907A-63A2-4895-8DEF-59F90C20380B}.Debug|Any CPU.Build.0 = Debug|Any CPU {DBF4907A-63A2-4895-8DEF-59F90C20380B}.Release|Any CPU.ActiveCfg = Release|Any CPU {DBF4907A-63A2-4895-8DEF-59F90C20380B}.Release|Any CPU.Build.0 = Release|Any CPU + {633AE0AD-C9D4-440D-874A-C0F4632DB75F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {633AE0AD-C9D4-440D-874A-C0F4632DB75F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {633AE0AD-C9D4-440D-874A-C0F4632DB75F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {633AE0AD-C9D4-440D-874A-C0F4632DB75F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -53,6 +59,7 @@ Global {866A028E-27DB-49A0-AC78-E5FEF247C099} = {037440DE-440B-4129-9F7A-09B42D00397E} {1D56534C-4009-42C2-A573-789CAE6B8AA9} = {7D0692CD-F95D-4BF9-8C63-B4A1C078DF23} {DBF4907A-63A2-4895-8DEF-59F90C20380B} = {CF817664-4CEC-4B6A-9C57-A0D687757D82} + {633AE0AD-C9D4-440D-874A-C0F4632DB75F} = {CF817664-4CEC-4B6A-9C57-A0D687757D82} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {43C32ED4-D39A-4E27-AE99-7BB8C883833C} From dc2c98e5d6d9518641f140f510305e8fd3172c16 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Sat, 23 Nov 2019 07:41:24 +1000 Subject: [PATCH 7/7] Drop explicit private modifier --- .../ConsoleLoggerConfigurationExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs index 01b085b..d6c2504 100644 --- a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs @@ -28,7 +28,7 @@ namespace Serilog /// public static class ConsoleLoggerConfigurationExtensions { - private static object DefaultSyncRoot = new object(); + static object DefaultSyncRoot = new object(); const string DefaultConsoleOutputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"; ///