From 7a388ebbdf327e67b257f8c15309fd673a67b51c Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Wed, 29 Nov 2023 06:44:03 +1000 Subject: [PATCH 1/7] Dev version bump [skip ci] --- src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj b/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj index 64aa0ba..7caeb63 100644 --- a/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj +++ b/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj @@ -1,7 +1,7 @@ A Serilog sink that writes log events to the console/terminal. - 5.0.1 + 5.0.2 Serilog Contributors net462;net471 $(TargetFrameworks);netstandard2.1;netstandard2.0;net5.0;net6.0;net7.0 From 1f0919ed791159781c234851d338619c18a505ff Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Wed, 29 Nov 2023 07:57:42 +1000 Subject: [PATCH 2/7] Remove obsolete Gitter link from README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b5d27bc..397b2e5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Serilog.Sinks.Console [![Build status](https://ci.appveyor.com/api/projects/status/w1w3m1wyk3in1c96/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-sinks-console/branch/master) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Sinks.Console.svg?style=flat)](https://www.nuget.org/packages/Serilog.Sinks.Console/) [![Documentation](https://img.shields.io/badge/docs-wiki-yellow.svg)](https://github.com/serilog/serilog/wiki) [![Join the chat at https://gitter.im/serilog/serilog](https://img.shields.io/gitter/room/serilog/serilog.svg)](https://gitter.im/serilog/serilog) [![Help](https://img.shields.io/badge/stackoverflow-serilog-orange.svg)](http://stackoverflow.com/questions/tagged/serilog) +# Serilog.Sinks.Console [![Build status](https://ci.appveyor.com/api/projects/status/w1w3m1wyk3in1c96/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-sinks-console/branch/master) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Sinks.Console.svg?style=flat)](https://www.nuget.org/packages/Serilog.Sinks.Console/) [![Documentation](https://img.shields.io/badge/docs-wiki-yellow.svg)](https://github.com/serilog/serilog/wiki) [![Help](https://img.shields.io/badge/stackoverflow-serilog-orange.svg)](http://stackoverflow.com/questions/tagged/serilog) A Serilog sink that writes log events to the Windows Console or an ANSI terminal via standard output. Coloring and custom themes are supported, including ANSI 256-color themes on macOS, Linux and Windows 10. The default output is plain text; JSON formatting can be plugged in using a package such as [_Serilog.Formatting.Compact_](https://github.com/serilog/serilog-formatting-compact). From cf2c80d5f4839e1a77f70a9d58b3f34ba3baf03c Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Sat, 16 Mar 2024 11:18:14 +0300 Subject: [PATCH 3/7] Support NO_COLOR environment variable --- .../ConsoleAuditLoggerConfigurationExtensions.cs | 3 ++- .../ConsoleLoggerConfigurationExtensions.cs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Serilog.Sinks.Console/ConsoleAuditLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.Console/ConsoleAuditLoggerConfigurationExtensions.cs index 6073c37..370147e 100644 --- a/src/Serilog.Sinks.Console/ConsoleAuditLoggerConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Console/ConsoleAuditLoggerConfigurationExtensions.cs @@ -63,7 +63,8 @@ public static LoggerConfiguration Console( if (sinkConfiguration is null) throw new ArgumentNullException(nameof(sinkConfiguration)); if (outputTemplate is null) throw new ArgumentNullException(nameof(outputTemplate)); - var appliedTheme = !applyThemeToRedirectedOutput && (System.Console.IsOutputRedirected || System.Console.IsErrorRedirected) ? + // see https://no-color.org/ + var appliedTheme = !applyThemeToRedirectedOutput && (System.Console.IsOutputRedirected || System.Console.IsErrorRedirected) || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NO_COLOR")) ? ConsoleTheme.None : theme ?? SystemConsoleThemes.Literate; diff --git a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs index cca312a..44fa2d1 100644 --- a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs @@ -59,14 +59,15 @@ public static LoggerConfiguration Console( IFormatProvider? formatProvider = null, LoggingLevelSwitch? levelSwitch = null, LogEventLevel? standardErrorFromLevel = null, - ConsoleTheme? theme = null, + ConsoleTheme? theme = null, bool applyThemeToRedirectedOutput = false, object? syncRoot = null) { if (sinkConfiguration is null) throw new ArgumentNullException(nameof(sinkConfiguration)); if (outputTemplate is null) throw new ArgumentNullException(nameof(outputTemplate)); - var appliedTheme = !applyThemeToRedirectedOutput && (System.Console.IsOutputRedirected || System.Console.IsErrorRedirected) ? + // see https://no-color.org/ + var appliedTheme = !applyThemeToRedirectedOutput && (System.Console.IsOutputRedirected || System.Console.IsErrorRedirected) || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NO_COLOR")) ? ConsoleTheme.None : theme ?? SystemConsoleThemes.Literate; From ca14c12d72fff65c180b7c8c1fc2dde4031e8bb5 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Mon, 18 Mar 2024 09:05:42 +1000 Subject: [PATCH 4/7] Minor version bump - addition of `NO_COLOR` support --- src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj b/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj index 7caeb63..debb986 100644 --- a/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj +++ b/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj @@ -1,7 +1,7 @@ A Serilog sink that writes log events to the console/terminal. - 5.0.2 + 5.1.0 Serilog Contributors net462;net471 $(TargetFrameworks);netstandard2.1;netstandard2.0;net5.0;net6.0;net7.0 From a9308efd1cc0eafbef376a3985900ca55d69cc8b Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Mon, 18 Mar 2024 09:06:39 +1000 Subject: [PATCH 5/7] Delete .travis.yml (Travis is no longer used) [skip ci] --- .travis.yml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2ed804c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: csharp - -matrix: - include: - - os: linux # Ubuntu 14.04 - dist: xenial - sudo: required - dotnet: 2.2.401 - mono: none - group: edge - -script: - - ./build.sh \ No newline at end of file From fa07aaf894027505d67264e1056abf815af67075 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Fri, 7 Jun 2024 13:36:44 +1000 Subject: [PATCH 6/7] Update to Serilog 4, file scoped namespaces --- Build.ps1 | 42 +- appveyor.yml | 4 +- sample/ConsoleDemo/Program.cs | 49 +- sample/SyncWritesDemo/Program.cs | 81 +- ...nsoleAuditLoggerConfigurationExtensions.cs | 151 ++-- .../ConsoleLoggerConfigurationExtensions.cs | 129 ++-- .../Serilog.Sinks.Console.csproj | 14 +- .../Sinks/SystemConsole/ConsoleSink.cs | 43 +- .../Formatting/ThemedDisplayValueFormatter.cs | 39 +- .../Formatting/ThemedJsonValueFormatter.cs | 41 +- .../Formatting/ThemedValueFormatter.cs | 25 +- .../Formatting/ThemedValueFormatterState.cs | 17 +- .../Output/EventPropertyTokenRenderer.cs | 21 +- .../Output/ExceptionTokenRenderer.cs | 19 +- .../Output/LevelTokenRenderer.cs | 37 +- .../MessageTemplateOutputTokenRenderer.cs | 21 +- .../Output/NewLineTokenRenderer.cs | 19 +- .../Output/OutputTemplateRenderer.cs | 19 +- .../Output/OutputTemplateTokenRenderer.cs | 11 +- .../Output/PropertiesTokenRenderer.cs | 27 +- .../SystemConsole/Output/TextTokenRenderer.cs | 19 +- .../Output/TimestampTokenRenderer.cs | 47 +- .../SystemConsole/Platform/WindowsConsole.cs | 43 +- .../Rendering/AlignmentExtensions.cs | 9 +- .../Sinks/SystemConsole/Rendering/Casing.cs | 23 +- .../Sinks/SystemConsole/Rendering/Padding.cs | 25 +- .../ThemedMessageTemplateRenderer.cs | 43 +- .../SystemConsole/Themes/AnsiConsoleTheme.cs | 81 +- .../SystemConsole/Themes/AnsiConsoleThemes.cs | 169 +++-- .../Themes/AnsiEscapeSequence.cs | 45 +- .../SystemConsole/Themes/ConsoleTheme.cs | 71 +- .../SystemConsole/Themes/ConsoleThemeStyle.cs | 187 +++-- .../SystemConsole/Themes/EmptyConsoleTheme.cs | 17 +- .../Sinks/SystemConsole/Themes/StyleReset.cs | 19 +- .../Themes/SystemConsoleTheme.cs | 73 +- .../Themes/SystemConsoleThemeStyle.cs | 25 +- .../Themes/SystemConsoleThemes.cs | 129 ++-- ...AuditLoggerConfigurationExtensionsTests.cs | 77 +- ...nsoleLoggerConfigurationExtensionsTests.cs | 77 +- .../ThemedDisplayValueFormatterTests.cs | 27 +- .../ThemedJsonValueFormatterTests.cs | 207 +++--- .../Output/OutputTemplateRendererTests.cs | 693 +++++++++--------- .../ThemedMessageTemplateRendererTests.cs | 379 +++++----- .../Support/DelegatingSink.cs | 45 +- .../Support/TracingConsoleTheme.cs | 31 +- 45 files changed, 1655 insertions(+), 1715 deletions(-) diff --git a/Build.ps1 b/Build.ps1 index b0ac93a..ba41ab1 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -1,12 +1,9 @@ -Write-Output "build: Build started" - -& dotnet --info -& dotnet --list-sdks +echo "build: Build started" Push-Location $PSScriptRoot if(Test-Path .\artifacts) { - Write-Output "build: Cleaning .\artifacts" + echo "build: Cleaning .\artifacts" Remove-Item .\artifacts -Force -Recurse } @@ -18,45 +15,34 @@ $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 ""] -Write-Output "build: Package version suffix is $suffix" -Write-Output "build: Build version suffix is $buildSuffix" +echo "build: Package version suffix is $suffix" +echo "build: Build version suffix is $buildSuffix" -foreach ($src in Get-ChildItem src/*) { +foreach ($src in ls src/*) { Push-Location $src - Write-Output "build: Packaging project in $src" + echo "build: Packaging project in $src" - & dotnet build -c Release --version-suffix=$buildSuffix + & dotnet build -c Release --version-suffix=$buildSuffix -p:EnableSourceLink=true if ($suffix) { - & dotnet pack -c Release --include-source -o ..\..\artifacts --version-suffix=$suffix --no-build + & dotnet pack -c Release -o ..\..\artifacts --version-suffix=$suffix --no-build } else { - & dotnet pack -c Release --include-source -o ..\..\artifacts --no-build + & dotnet pack -c Release -o ..\..\artifacts --no-build } - if($LASTEXITCODE -ne 0) { exit 1 } - - Pop-Location -} - -foreach ($sample in Get-ChildItem sample/*) { - Push-Location $sample - - Write-Output "build: Testing project in $sample" - - & dotnet build -c Release --version-suffix=$buildSuffix - if($LASTEXITCODE -ne 0) { exit 3 } + if($LASTEXITCODE -ne 0) { throw "build failed" } Pop-Location } -foreach ($test in Get-ChildItem test/*.Tests) { +foreach ($test in ls test/*.Tests) { Push-Location $test - Write-Output "build: Testing project in $test" + echo "build: Testing project in $test" & dotnet test -c Release - if($LASTEXITCODE -ne 0) { exit 3 } + if($LASTEXITCODE -ne 0) { throw "tests failed" } Pop-Location } -Pop-Location +Pop-Location \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index c6dd7f8..0a0eb08 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,13 +3,13 @@ skip_tags: true image: Visual Studio 2022 test: off build_script: -- ps: ./Build.ps1 +- pwsh: ./Build.ps1 artifacts: - path: artifacts/Serilog.*.nupkg deploy: - provider: NuGet api_key: - secure: dX4ewxGxhiNURkqJPuZQ8GQNjLvb8oZrHBThVotn+9GSMyQzeKXFpHkN04ykOfgc + secure: ZpUO4ECx4c/V0Ecj04cfV1UGd+ZABeEG9DDW2fjG8vITjNYhmbiiJH0qNOnRy2G3 skip_symbols: true on: branch: /^(main|dev)$/ diff --git a/sample/ConsoleDemo/Program.cs b/sample/ConsoleDemo/Program.cs index 73d50d8..3ff0ec4 100644 --- a/sample/ConsoleDemo/Program.cs +++ b/sample/ConsoleDemo/Program.cs @@ -3,38 +3,37 @@ using System; using System.Threading; -namespace ConsoleDemo +namespace ConsoleDemo; + +public static class Program { - public static class Program + public static void Main() { - public static void Main() - { - Log.Logger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo.Console(theme: AnsiConsoleTheme.Code) - .CreateLogger(); - - try - { - Log.Debug("Getting started"); + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Verbose() + .WriteTo.Console(theme: AnsiConsoleTheme.Code) + .CreateLogger(); - Log.Information("Hello {Name} from thread {ThreadId}", Environment.GetEnvironmentVariable("USERNAME"), Thread.CurrentThread.ManagedThreadId); + try + { + Log.Debug("Getting started"); - Log.Warning("No coins remain at position {@Position}", new { Lat = 25, Long = 134 }); + Log.Information("Hello {Name} from thread {ThreadId}", Environment.GetEnvironmentVariable("USERNAME"), Thread.CurrentThread.ManagedThreadId); - Fail(); - } - catch (Exception e) - { - Log.Error(e, "Something went wrong"); - } + Log.Warning("No coins remain at position {@Position}", new { Lat = 25, Long = 134 }); - Log.CloseAndFlush(); + Fail(); } - - static void Fail() + catch (Exception e) { - throw new DivideByZeroException(); + Log.Error(e, "Something went wrong"); } + + Log.CloseAndFlush(); + } + + static void Fail() + { + throw new DivideByZeroException(); } -} +} \ No newline at end of file diff --git a/sample/SyncWritesDemo/Program.cs b/sample/SyncWritesDemo/Program.cs index 5120393..3220c12 100644 --- a/sample/SyncWritesDemo/Program.cs +++ b/sample/SyncWritesDemo/Program.cs @@ -4,54 +4,53 @@ using System.Threading; using System.Threading.Tasks; -namespace SyncWritesDemo +namespace SyncWritesDemo; + +public static class Program { - public static class Program + public static void Main(string[] args) { - public static void Main(string[] args) - { - Console.WriteLine("A sample of how to sync writes to the console sink."); + Console.WriteLine("A sample of how to sync writes to the console sink."); - if (args != null && args.Length == 1) + if (args != null && args.Length == 1) + { + switch (args[0]) { - 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; - } + 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(); + Console.WriteLine("Expecting one of the following arguments:{0}--sync-root-default{0}--sync-root-separate{0}--sync-root-same", Environment.NewLine); + } - var logger2 = new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("Logger", "logger2") - .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger2) - .CreateLogger(); + 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 options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; - 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); - }); - } + var logger2 = new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("Logger", "logger2") + .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger2) + .CreateLogger(); + + var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; + 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); + }); } -} +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/ConsoleAuditLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.Console/ConsoleAuditLoggerConfigurationExtensions.cs index 370147e..9fe62cd 100644 --- a/src/Serilog.Sinks.Console/ConsoleAuditLoggerConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Console/ConsoleAuditLoggerConfigurationExtensions.cs @@ -21,90 +21,89 @@ using Serilog.Sinks.SystemConsole.Themes; using System; -namespace Serilog +namespace Serilog; + +/// +/// Adds the AuditTo.Console() extension method to . +/// +public static class ConsoleAuditLoggerConfigurationExtensions { /// - /// Adds the AuditTo.Console() extension method to . + /// Writes log events to . /// - public static class ConsoleAuditLoggerConfigurationExtensions + /// Logger sink configuration. + /// The minimum level for + /// 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. + /// Specifies the level at which events will be written to standard error. + /// The theme to apply to the styled output. If not specified, + /// uses . + /// Applies the selected or default theme even when output redirection is detected. + /// Configuration object allowing method chaining. + /// When is null + /// When is null + public static LoggerConfiguration Console( + this LoggerAuditSinkConfiguration sinkConfiguration, + LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, + string outputTemplate = ConsoleLoggerConfigurationExtensions.DefaultConsoleOutputTemplate, + IFormatProvider? formatProvider = null, + LoggingLevelSwitch? levelSwitch = null, + LogEventLevel? standardErrorFromLevel = null, + ConsoleTheme? theme = null, + bool applyThemeToRedirectedOutput = false, + object? syncRoot = null) { - /// - /// Writes log events to . - /// - /// Logger sink configuration. - /// The minimum level for - /// 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. - /// Specifies the level at which events will be written to standard error. - /// The theme to apply to the styled output. If not specified, - /// uses . - /// Applies the selected or default theme even when output redirection is detected. - /// Configuration object allowing method chaining. - /// When is null - /// When is null - public static LoggerConfiguration Console( - this LoggerAuditSinkConfiguration sinkConfiguration, - LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, - string outputTemplate = ConsoleLoggerConfigurationExtensions.DefaultConsoleOutputTemplate, - IFormatProvider? formatProvider = null, - LoggingLevelSwitch? levelSwitch = null, - LogEventLevel? standardErrorFromLevel = null, - ConsoleTheme? theme = null, - bool applyThemeToRedirectedOutput = false, - object? syncRoot = null) - { - if (sinkConfiguration is null) throw new ArgumentNullException(nameof(sinkConfiguration)); - if (outputTemplate is null) throw new ArgumentNullException(nameof(outputTemplate)); + if (sinkConfiguration is null) throw new ArgumentNullException(nameof(sinkConfiguration)); + if (outputTemplate is null) throw new ArgumentNullException(nameof(outputTemplate)); - // see https://no-color.org/ - var appliedTheme = !applyThemeToRedirectedOutput && (System.Console.IsOutputRedirected || System.Console.IsErrorRedirected) || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NO_COLOR")) ? - ConsoleTheme.None : - theme ?? SystemConsoleThemes.Literate; + // see https://no-color.org/ + var appliedTheme = !applyThemeToRedirectedOutput && (System.Console.IsOutputRedirected || System.Console.IsErrorRedirected) || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NO_COLOR")) ? + ConsoleTheme.None : + theme ?? SystemConsoleThemes.Literate; - syncRoot ??= ConsoleLoggerConfigurationExtensions.DefaultSyncRoot; + syncRoot ??= ConsoleLoggerConfigurationExtensions.DefaultSyncRoot; - var formatter = new OutputTemplateRenderer(appliedTheme, outputTemplate, formatProvider); - return sinkConfiguration.Sink(new ConsoleSink(appliedTheme, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); - } + var formatter = new OutputTemplateRenderer(appliedTheme, outputTemplate, formatProvider); + return sinkConfiguration.Sink(new ConsoleSink(appliedTheme, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); + } - /// - /// Writes log events to . - /// - /// 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 - /// to be changed at runtime. - /// Specifies the level at which events will be written to standard error. - /// Configuration object allowing method chaining. - /// When is null - /// When is null - public static LoggerConfiguration Console( - this LoggerAuditSinkConfiguration sinkConfiguration, - ITextFormatter formatter, - LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, - LoggingLevelSwitch? levelSwitch = null, - LogEventLevel? standardErrorFromLevel = null, - object? syncRoot = null) - { - if (sinkConfiguration is null) throw new ArgumentNullException(nameof(sinkConfiguration)); - if (formatter is null) throw new ArgumentNullException(nameof(formatter)); + /// + /// Writes log events to . + /// + /// 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 + /// to be changed at runtime. + /// Specifies the level at which events will be written to standard error. + /// Configuration object allowing method chaining. + /// When is null + /// When is null + public static LoggerConfiguration Console( + this LoggerAuditSinkConfiguration sinkConfiguration, + ITextFormatter formatter, + LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, + LoggingLevelSwitch? levelSwitch = null, + LogEventLevel? standardErrorFromLevel = null, + object? syncRoot = null) + { + if (sinkConfiguration is null) throw new ArgumentNullException(nameof(sinkConfiguration)); + if (formatter is null) throw new ArgumentNullException(nameof(formatter)); - syncRoot ??= ConsoleLoggerConfigurationExtensions.DefaultSyncRoot; + syncRoot ??= ConsoleLoggerConfigurationExtensions.DefaultSyncRoot; - return sinkConfiguration.Sink(new ConsoleSink(ConsoleTheme.None, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); - } + return sinkConfiguration.Sink(new ConsoleSink(ConsoleTheme.None, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); } -} +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs index 44fa2d1..a994890 100644 --- a/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Console/ConsoleLoggerConfigurationExtensions.cs @@ -21,48 +21,48 @@ using Serilog.Sinks.SystemConsole.Themes; using System; -namespace Serilog +namespace Serilog; + +/// +/// Adds the WriteTo.Console() extension method to . +/// +public static class ConsoleLoggerConfigurationExtensions { + internal static readonly object DefaultSyncRoot = new object(); + internal const string DefaultConsoleOutputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"; + /// - /// Adds the WriteTo.Console() extension method to . + /// Writes log events to . /// - public static class ConsoleLoggerConfigurationExtensions + /// Logger sink configuration. + /// The minimum level for + /// 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. + /// Specifies the level at which events will be written to standard error. + /// The theme to apply to the styled output. If not specified, + /// uses . + /// Applies the selected or default theme even when output redirection is detected. + /// Configuration object allowing method chaining. + /// When is null + /// When is null + public static LoggerConfiguration Console( + this LoggerSinkConfiguration sinkConfiguration, + LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, + string outputTemplate = DefaultConsoleOutputTemplate, + IFormatProvider? formatProvider = null, + LoggingLevelSwitch? levelSwitch = null, + LogEventLevel? standardErrorFromLevel = null, + ConsoleTheme? theme = null, + bool applyThemeToRedirectedOutput = false, + object? syncRoot = null) { - internal static readonly object DefaultSyncRoot = new object(); - internal const string DefaultConsoleOutputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"; - - /// - /// Writes log events to . - /// - /// Logger sink configuration. - /// The minimum level for - /// 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. - /// Specifies the level at which events will be written to standard error. - /// The theme to apply to the styled output. If not specified, - /// uses . - /// Applies the selected or default theme even when output redirection is detected. - /// Configuration object allowing method chaining. - /// When is null - /// When is null - public static LoggerConfiguration Console( - this LoggerSinkConfiguration sinkConfiguration, - LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, - string outputTemplate = DefaultConsoleOutputTemplate, - IFormatProvider? formatProvider = null, - LoggingLevelSwitch? levelSwitch = null, - LogEventLevel? standardErrorFromLevel = null, - ConsoleTheme? theme = null, - bool applyThemeToRedirectedOutput = false, - object? syncRoot = null) - { if (sinkConfiguration is null) throw new ArgumentNullException(nameof(sinkConfiguration)); if (outputTemplate is null) throw new ArgumentNullException(nameof(outputTemplate)); @@ -77,31 +77,31 @@ public static LoggerConfiguration Console( return sinkConfiguration.Sink(new ConsoleSink(appliedTheme, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); } - /// - /// Writes log events to . - /// - /// 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 - /// to be changed at runtime. - /// Specifies the level at which events will be written to standard error. - /// Configuration object allowing method chaining. - /// When is null - /// When is null - public static LoggerConfiguration Console( - this LoggerSinkConfiguration sinkConfiguration, - ITextFormatter formatter, - LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, - LoggingLevelSwitch? levelSwitch = null, - LogEventLevel? standardErrorFromLevel = null, - object? syncRoot = null) - { + /// + /// Writes log events to . + /// + /// 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 + /// to be changed at runtime. + /// Specifies the level at which events will be written to standard error. + /// Configuration object allowing method chaining. + /// When is null + /// When is null + public static LoggerConfiguration Console( + this LoggerSinkConfiguration sinkConfiguration, + ITextFormatter formatter, + LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, + LoggingLevelSwitch? levelSwitch = null, + LogEventLevel? standardErrorFromLevel = null, + object? syncRoot = null) + { if (sinkConfiguration is null) throw new ArgumentNullException(nameof(sinkConfiguration)); if (formatter is null) throw new ArgumentNullException(nameof(formatter)); @@ -109,5 +109,4 @@ public static LoggerConfiguration Console( return sinkConfiguration.Sink(new ConsoleSink(ConsoleTheme.None, formatter, standardErrorFromLevel, syncRoot), restrictedToMinimumLevel, levelSwitch); } - } -} +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj b/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj index debb986..38a3d4f 100644 --- a/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj +++ b/src/Serilog.Sinks.Console/Serilog.Sinks.Console.csproj @@ -1,10 +1,10 @@ A Serilog sink that writes log events to the console/terminal. - 5.1.0 + 6.0.0 Serilog Contributors net462;net471 - $(TargetFrameworks);netstandard2.1;netstandard2.0;net5.0;net6.0;net7.0 + $(TargetFrameworks);netstandard2.0;net6.0;net8.0 enable ../../assets/Serilog.snk true @@ -26,21 +26,17 @@ $(DefineConstants);RUNTIME_INFORMATION - - $(DefineConstants);FEATURE_SPAN - - $(DefineConstants);FEATURE_SPAN - + $(DefineConstants);FEATURE_SPAN - - + + diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs index e1c1bea..3979f1a 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/ConsoleSink.cs @@ -21,36 +21,36 @@ using System.IO; using System.Text; -namespace Serilog.Sinks.SystemConsole +namespace Serilog.Sinks.SystemConsole; + +class ConsoleSink : ILogEventSink { - class ConsoleSink : ILogEventSink - { - readonly LogEventLevel? _standardErrorFromLevel; - readonly ConsoleTheme _theme; - readonly ITextFormatter _formatter; - readonly object _syncRoot; + readonly LogEventLevel? _standardErrorFromLevel; + readonly ConsoleTheme _theme; + readonly ITextFormatter _formatter; + readonly object _syncRoot; - const int DefaultWriteBufferCapacity = 256; + const int DefaultWriteBufferCapacity = 256; - static ConsoleSink() - { + static ConsoleSink() + { WindowsConsole.EnableVirtualTerminalProcessing(); } - public ConsoleSink( - ConsoleTheme theme, - ITextFormatter formatter, - LogEventLevel? standardErrorFromLevel, - object syncRoot) - { + public ConsoleSink( + ConsoleTheme theme, + ITextFormatter formatter, + LogEventLevel? standardErrorFromLevel, + object syncRoot) + { _standardErrorFromLevel = standardErrorFromLevel; _theme = theme ?? throw new ArgumentNullException(nameof(theme)); _formatter = formatter; _syncRoot = syncRoot ?? throw new ArgumentNullException(nameof(syncRoot)); } - public void Emit(LogEvent logEvent) - { + public void Emit(LogEvent logEvent) + { var output = SelectOutputStream(logEvent.Level); // ANSI escape codes can be pre-rendered into a buffer; however, if we're on Windows and @@ -77,12 +77,11 @@ public void Emit(LogEvent logEvent) } } - TextWriter SelectOutputStream(LogEventLevel logEventLevel) - { + TextWriter SelectOutputStream(LogEventLevel logEventLevel) + { if (_standardErrorFromLevel is null) return Console.Out; return logEventLevel < _standardErrorFromLevel ? Console.Out : Console.Error; } - } -} +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedDisplayValueFormatter.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedDisplayValueFormatter.cs index 3093bd6..64aae39 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedDisplayValueFormatter.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedDisplayValueFormatter.cs @@ -18,32 +18,32 @@ using Serilog.Formatting.Json; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Formatting +namespace Serilog.Sinks.SystemConsole.Formatting; + +class ThemedDisplayValueFormatter : ThemedValueFormatter { - class ThemedDisplayValueFormatter : ThemedValueFormatter - { - readonly IFormatProvider? _formatProvider; + readonly IFormatProvider? _formatProvider; - public ThemedDisplayValueFormatter(ConsoleTheme theme, IFormatProvider? formatProvider) - : base(theme) - { + public ThemedDisplayValueFormatter(ConsoleTheme theme, IFormatProvider? formatProvider) + : base(theme) + { _formatProvider = formatProvider; } - public override ThemedValueFormatter SwitchTheme(ConsoleTheme theme) - { + public override ThemedValueFormatter SwitchTheme(ConsoleTheme theme) + { return new ThemedDisplayValueFormatter(theme, _formatProvider); } - protected override int VisitScalarValue(ThemedValueFormatterState state, ScalarValue scalar) - { + protected override int VisitScalarValue(ThemedValueFormatterState state, ScalarValue scalar) + { if (scalar is null) throw new ArgumentNullException(nameof(scalar)); return FormatLiteralValue(scalar, state.Output, state.Format); } - protected override int VisitSequenceValue(ThemedValueFormatterState state, SequenceValue sequence) - { + protected override int VisitSequenceValue(ThemedValueFormatterState state, SequenceValue sequence) + { if (sequence is null) throw new ArgumentNullException(nameof(sequence)); @@ -71,8 +71,8 @@ protected override int VisitSequenceValue(ThemedValueFormatterState state, Seque return count; } - protected override int VisitStructureValue(ThemedValueFormatterState state, StructureValue structure) - { + protected override int VisitStructureValue(ThemedValueFormatterState state, StructureValue structure) + { var count = 0; if (structure.TypeTag != null) @@ -114,8 +114,8 @@ protected override int VisitStructureValue(ThemedValueFormatterState state, Stru return count; } - protected override int VisitDictionaryValue(ThemedValueFormatterState state, DictionaryValue dictionary) - { + protected override int VisitDictionaryValue(ThemedValueFormatterState state, DictionaryValue dictionary) + { var count = 0; using (ApplyStyle(state.Output, ConsoleThemeStyle.TertiaryText, ref count)) @@ -150,8 +150,8 @@ protected override int VisitDictionaryValue(ThemedValueFormatterState state, Dic return count; } - public int FormatLiteralValue(ScalarValue scalar, TextWriter output, string? format) - { + public int FormatLiteralValue(ScalarValue scalar, TextWriter output, string? format) + { var value = scalar.Value; var count = 0; @@ -210,5 +210,4 @@ value is decimal || value is byte || value is sbyte || value is short || return count; } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedJsonValueFormatter.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedJsonValueFormatter.cs index ec6d5d1..1d913ec 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedJsonValueFormatter.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedJsonValueFormatter.cs @@ -19,27 +19,27 @@ using Serilog.Formatting.Json; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Formatting +namespace Serilog.Sinks.SystemConsole.Formatting; + +class ThemedJsonValueFormatter : ThemedValueFormatter { - class ThemedJsonValueFormatter : ThemedValueFormatter - { - readonly ThemedDisplayValueFormatter _displayFormatter; - readonly IFormatProvider? _formatProvider; + readonly ThemedDisplayValueFormatter _displayFormatter; + readonly IFormatProvider? _formatProvider; - public ThemedJsonValueFormatter(ConsoleTheme theme, IFormatProvider? formatProvider) - : base(theme) - { + public ThemedJsonValueFormatter(ConsoleTheme theme, IFormatProvider? formatProvider) + : base(theme) + { _displayFormatter = new ThemedDisplayValueFormatter(theme, formatProvider); _formatProvider = formatProvider; } - public override ThemedValueFormatter SwitchTheme(ConsoleTheme theme) - { + public override ThemedValueFormatter SwitchTheme(ConsoleTheme theme) + { return new ThemedJsonValueFormatter(theme, _formatProvider); } - protected override int VisitScalarValue(ThemedValueFormatterState state, ScalarValue scalar) - { + protected override int VisitScalarValue(ThemedValueFormatterState state, ScalarValue scalar) + { if (scalar is null) throw new ArgumentNullException(nameof(scalar)); @@ -50,8 +50,8 @@ protected override int VisitScalarValue(ThemedValueFormatterState state, ScalarV return FormatLiteralValue(scalar, state.Output); } - protected override int VisitSequenceValue(ThemedValueFormatterState state, SequenceValue sequence) - { + protected override int VisitSequenceValue(ThemedValueFormatterState state, SequenceValue sequence) + { if (sequence == null) throw new ArgumentNullException(nameof(sequence)); @@ -79,8 +79,8 @@ protected override int VisitSequenceValue(ThemedValueFormatterState state, Seque return count; } - protected override int VisitStructureValue(ThemedValueFormatterState state, StructureValue structure) - { + protected override int VisitStructureValue(ThemedValueFormatterState state, StructureValue structure) + { var count = 0; using (ApplyStyle(state.Output, ConsoleThemeStyle.TertiaryText, ref count)) @@ -129,8 +129,8 @@ protected override int VisitStructureValue(ThemedValueFormatterState state, Stru return count; } - protected override int VisitDictionaryValue(ThemedValueFormatterState state, DictionaryValue dictionary) - { + protected override int VisitDictionaryValue(ThemedValueFormatterState state, DictionaryValue dictionary) + { var count = 0; using (ApplyStyle(state.Output, ConsoleThemeStyle.TertiaryText, ref count)) @@ -168,8 +168,8 @@ protected override int VisitDictionaryValue(ThemedValueFormatterState state, Dic return count; } - int FormatLiteralValue(ScalarValue scalar, TextWriter output) - { + int FormatLiteralValue(ScalarValue scalar, TextWriter output) + { var value = scalar.Value; var count = 0; @@ -252,5 +252,4 @@ int FormatLiteralValue(ScalarValue scalar, TextWriter output) return count; } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedValueFormatter.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedValueFormatter.cs index 34be339..f2e4e92 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedValueFormatter.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedValueFormatter.cs @@ -18,27 +18,26 @@ using Serilog.Events; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Formatting +namespace Serilog.Sinks.SystemConsole.Formatting; + +abstract class ThemedValueFormatter : LogEventPropertyValueVisitor { - abstract class ThemedValueFormatter : LogEventPropertyValueVisitor - { - readonly ConsoleTheme _theme; + readonly ConsoleTheme _theme; - protected ThemedValueFormatter(ConsoleTheme theme) - { + protected ThemedValueFormatter(ConsoleTheme theme) + { _theme = theme ?? throw new ArgumentNullException(nameof(theme)); } - protected StyleReset ApplyStyle(TextWriter output, ConsoleThemeStyle style, ref int invisibleCharacterCount) - { + protected StyleReset ApplyStyle(TextWriter output, ConsoleThemeStyle style, ref int invisibleCharacterCount) + { return _theme.Apply(output, style, ref invisibleCharacterCount); } - public int Format(LogEventPropertyValue value, TextWriter output, string? format, bool literalTopLevel = false) - { + public int Format(LogEventPropertyValue value, TextWriter output, string? format, bool literalTopLevel = false) + { return Visit(new ThemedValueFormatterState { Output = output, Format = format, IsTopLevel = literalTopLevel }, value); } - public abstract ThemedValueFormatter SwitchTheme(ConsoleTheme theme); - } -} + public abstract ThemedValueFormatter SwitchTheme(ConsoleTheme theme); +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedValueFormatterState.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedValueFormatterState.cs index a5f5a86..52e5a4e 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedValueFormatterState.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Formatting/ThemedValueFormatterState.cs @@ -14,14 +14,13 @@ using System.IO; -namespace Serilog.Sinks.SystemConsole.Formatting +namespace Serilog.Sinks.SystemConsole.Formatting; + +struct ThemedValueFormatterState { - struct ThemedValueFormatterState - { - public TextWriter Output; - public string? Format; - public bool IsTopLevel; + public TextWriter Output; + public string? Format; + public bool IsTopLevel; - public ThemedValueFormatterState Nest() => new ThemedValueFormatterState { Output = Output }; - } -} + public ThemedValueFormatterState Nest() => new ThemedValueFormatterState { Output = Output }; +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/EventPropertyTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/EventPropertyTokenRenderer.cs index d4fe511..61d4fb9 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/EventPropertyTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/EventPropertyTokenRenderer.cs @@ -19,23 +19,23 @@ using Serilog.Sinks.SystemConsole.Rendering; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class EventPropertyTokenRenderer : OutputTemplateTokenRenderer { - class EventPropertyTokenRenderer : OutputTemplateTokenRenderer - { - readonly ConsoleTheme _theme; - readonly PropertyToken _token; - readonly IFormatProvider? _formatProvider; + readonly ConsoleTheme _theme; + readonly PropertyToken _token; + readonly IFormatProvider? _formatProvider; - public EventPropertyTokenRenderer(ConsoleTheme theme, PropertyToken token, IFormatProvider? formatProvider) - { + public EventPropertyTokenRenderer(ConsoleTheme theme, PropertyToken token, IFormatProvider? formatProvider) + { _theme = theme; _token = token; _formatProvider = formatProvider; } - public override void Render(LogEvent logEvent, TextWriter output) - { + public override void Render(LogEvent logEvent, TextWriter output) + { // If a property is missing, don't render anything (message templates render the raw token here). if (!logEvent.Properties.TryGetValue(_token.PropertyName, out var propertyValue)) { @@ -67,5 +67,4 @@ public override void Render(LogEvent logEvent, TextWriter output) } } } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/ExceptionTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/ExceptionTokenRenderer.cs index a70c161..2fca227 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/ExceptionTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/ExceptionTokenRenderer.cs @@ -17,21 +17,21 @@ using Serilog.Parsing; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class ExceptionTokenRenderer : OutputTemplateTokenRenderer { - class ExceptionTokenRenderer : OutputTemplateTokenRenderer - { - const string StackFrameLinePrefix = " "; + const string StackFrameLinePrefix = " "; - readonly ConsoleTheme _theme; + readonly ConsoleTheme _theme; - public ExceptionTokenRenderer(ConsoleTheme theme, PropertyToken pt) - { + public ExceptionTokenRenderer(ConsoleTheme theme, PropertyToken pt) + { _theme = theme; } - public override void Render(LogEvent logEvent, TextWriter output) - { + public override void Render(LogEvent logEvent, TextWriter output) + { // Padding is never applied by this renderer. if (logEvent.Exception is null) @@ -48,5 +48,4 @@ public override void Render(LogEvent logEvent, TextWriter output) output.WriteLine(); } } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/LevelTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/LevelTokenRenderer.cs index 9cb9ed1..847e1f4 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/LevelTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/LevelTokenRenderer.cs @@ -19,31 +19,31 @@ using Serilog.Sinks.SystemConsole.Rendering; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class LevelTokenRenderer : OutputTemplateTokenRenderer { - class LevelTokenRenderer : OutputTemplateTokenRenderer - { - readonly ConsoleTheme _theme; - readonly PropertyToken _levelToken; + readonly ConsoleTheme _theme; + readonly PropertyToken _levelToken; - static readonly Dictionary Levels = new Dictionary - { - { LogEventLevel.Verbose, ConsoleThemeStyle.LevelVerbose }, - { LogEventLevel.Debug, ConsoleThemeStyle.LevelDebug }, - { LogEventLevel.Information, ConsoleThemeStyle.LevelInformation }, - { LogEventLevel.Warning, ConsoleThemeStyle.LevelWarning }, - { LogEventLevel.Error, ConsoleThemeStyle.LevelError }, - { LogEventLevel.Fatal, ConsoleThemeStyle.LevelFatal }, - }; + static readonly Dictionary Levels = new Dictionary + { + { LogEventLevel.Verbose, ConsoleThemeStyle.LevelVerbose }, + { LogEventLevel.Debug, ConsoleThemeStyle.LevelDebug }, + { LogEventLevel.Information, ConsoleThemeStyle.LevelInformation }, + { LogEventLevel.Warning, ConsoleThemeStyle.LevelWarning }, + { LogEventLevel.Error, ConsoleThemeStyle.LevelError }, + { LogEventLevel.Fatal, ConsoleThemeStyle.LevelFatal }, + }; - public LevelTokenRenderer(ConsoleTheme theme, PropertyToken levelToken) - { + public LevelTokenRenderer(ConsoleTheme theme, PropertyToken levelToken) + { _theme = theme; _levelToken = levelToken; } - public override void Render(LogEvent logEvent, TextWriter output) - { + public override void Render(LogEvent logEvent, TextWriter output) + { var moniker = LevelOutputFormat.GetLevelMoniker(logEvent.Level, _levelToken.Format); if (!Levels.TryGetValue(logEvent.Level, out var levelStyle)) levelStyle = ConsoleThemeStyle.Invalid; @@ -52,5 +52,4 @@ public override void Render(LogEvent logEvent, TextWriter output) using (_theme.Apply(output, levelStyle, ref _)) Padding.Apply(output, moniker, _levelToken.Alignment); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/MessageTemplateOutputTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/MessageTemplateOutputTokenRenderer.cs index 9f0997b..f171d70 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/MessageTemplateOutputTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/MessageTemplateOutputTokenRenderer.cs @@ -20,16 +20,16 @@ using Serilog.Sinks.SystemConsole.Rendering; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class MessageTemplateOutputTokenRenderer : OutputTemplateTokenRenderer { - class MessageTemplateOutputTokenRenderer : OutputTemplateTokenRenderer - { - readonly ConsoleTheme _theme; - readonly PropertyToken _token; - readonly ThemedMessageTemplateRenderer _renderer; + readonly ConsoleTheme _theme; + readonly PropertyToken _token; + readonly ThemedMessageTemplateRenderer _renderer; - public MessageTemplateOutputTokenRenderer(ConsoleTheme theme, PropertyToken token, IFormatProvider? formatProvider) - { + public MessageTemplateOutputTokenRenderer(ConsoleTheme theme, PropertyToken token, IFormatProvider? formatProvider) + { _theme = theme ?? throw new ArgumentNullException(nameof(theme)); _token = token ?? throw new ArgumentNullException(nameof(token)); @@ -53,8 +53,8 @@ public MessageTemplateOutputTokenRenderer(ConsoleTheme theme, PropertyToken toke _renderer = new ThemedMessageTemplateRenderer(theme, valueFormatter, isLiteral); } - public override void Render(LogEvent logEvent, TextWriter output) - { + public override void Render(LogEvent logEvent, TextWriter output) + { if (_token.Alignment is null || !_theme.CanBuffer) { _renderer.Render(logEvent.MessageTemplate, logEvent.Properties, output); @@ -66,5 +66,4 @@ public override void Render(LogEvent logEvent, TextWriter output) var value = buffer.ToString(); Padding.Apply(output, value, _token.Alignment.Value.Widen(invisible)); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/NewLineTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/NewLineTokenRenderer.cs index 4b072c3..2107f4b 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/NewLineTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/NewLineTokenRenderer.cs @@ -18,23 +18,22 @@ using Serilog.Parsing; using Serilog.Sinks.SystemConsole.Rendering; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class NewLineTokenRenderer : OutputTemplateTokenRenderer { - class NewLineTokenRenderer : OutputTemplateTokenRenderer - { - readonly Alignment? _alignment; + readonly Alignment? _alignment; - public NewLineTokenRenderer(Alignment? alignment) - { + public NewLineTokenRenderer(Alignment? alignment) + { _alignment = alignment; } - public override void Render(LogEvent logEvent, TextWriter output) - { + public override void Render(LogEvent logEvent, TextWriter output) + { if (_alignment.HasValue) Padding.Apply(output, Environment.NewLine, _alignment.Value.Widen(Environment.NewLine.Length)); else output.WriteLine(); } - } -} +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateRenderer.cs index f922290..2f8c743 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateRenderer.cs @@ -21,14 +21,14 @@ using Serilog.Parsing; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class OutputTemplateRenderer : ITextFormatter { - class OutputTemplateRenderer : ITextFormatter - { - readonly OutputTemplateTokenRenderer[] _renderers; + readonly OutputTemplateTokenRenderer[] _renderers; - public OutputTemplateRenderer(ConsoleTheme theme, string outputTemplate, IFormatProvider? formatProvider) - { + public OutputTemplateRenderer(ConsoleTheme theme, string outputTemplate, IFormatProvider? formatProvider) + { if (outputTemplate is null) throw new ArgumentNullException(nameof(outputTemplate)); var template = new MessageTemplateParser().Parse(outputTemplate); @@ -83,13 +83,12 @@ public OutputTemplateRenderer(ConsoleTheme theme, string outputTemplate, IFormat _renderers = renderers.ToArray(); } - public void Format(LogEvent logEvent, TextWriter output) - { + public void Format(LogEvent logEvent, TextWriter output) + { if (logEvent is null) throw new ArgumentNullException(nameof(logEvent)); if (output is null) throw new ArgumentNullException(nameof(output)); foreach (var renderer in _renderers) renderer.Render(logEvent, output); } - } -} +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateTokenRenderer.cs index 90f3c7e..a2b287e 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateTokenRenderer.cs @@ -15,10 +15,9 @@ using System.IO; using Serilog.Events; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +abstract class OutputTemplateTokenRenderer { - abstract class OutputTemplateTokenRenderer - { - public abstract void Render(LogEvent logEvent, TextWriter output); - } -} + public abstract void Render(LogEvent logEvent, TextWriter output); +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/PropertiesTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/PropertiesTokenRenderer.cs index 8e48fd0..051b186 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/PropertiesTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/PropertiesTokenRenderer.cs @@ -22,17 +22,17 @@ using Serilog.Sinks.SystemConsole.Rendering; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class PropertiesTokenRenderer : OutputTemplateTokenRenderer { - class PropertiesTokenRenderer : OutputTemplateTokenRenderer - { - readonly MessageTemplate _outputTemplate; - readonly ConsoleTheme _theme; - readonly PropertyToken _token; - readonly ThemedValueFormatter _valueFormatter; + readonly MessageTemplate _outputTemplate; + readonly ConsoleTheme _theme; + readonly PropertyToken _token; + readonly ThemedValueFormatter _valueFormatter; - public PropertiesTokenRenderer(ConsoleTheme theme, PropertyToken token, MessageTemplate outputTemplate, IFormatProvider? formatProvider) - { + public PropertiesTokenRenderer(ConsoleTheme theme, PropertyToken token, MessageTemplate outputTemplate, IFormatProvider? formatProvider) + { _outputTemplate = outputTemplate; _theme = theme ?? throw new ArgumentNullException(nameof(theme)); _token = token ?? throw new ArgumentNullException(nameof(token)); @@ -53,8 +53,8 @@ public PropertiesTokenRenderer(ConsoleTheme theme, PropertyToken token, MessageT : new ThemedDisplayValueFormatter(theme, formatProvider); } - public override void Render(LogEvent logEvent, TextWriter output) - { + public override void Render(LogEvent logEvent, TextWriter output) + { var included = logEvent.Properties .Where(p => !TemplateContainsPropertyName(logEvent.MessageTemplate, p.Key) && !TemplateContainsPropertyName(_outputTemplate, p.Key)) @@ -74,8 +74,8 @@ public override void Render(LogEvent logEvent, TextWriter output) Padding.Apply(output, str, _token.Alignment.Value.Widen(invisible)); } - static bool TemplateContainsPropertyName(MessageTemplate template, string propertyName) - { + static bool TemplateContainsPropertyName(MessageTemplate template, string propertyName) + { foreach (var token in template.Tokens) { if (token is PropertyToken namedProperty && @@ -87,5 +87,4 @@ static bool TemplateContainsPropertyName(MessageTemplate template, string proper return false; } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/TextTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/TextTokenRenderer.cs index 1394964..4106e29 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/TextTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/TextTokenRenderer.cs @@ -16,24 +16,23 @@ using Serilog.Events; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class TextTokenRenderer : OutputTemplateTokenRenderer { - class TextTokenRenderer : OutputTemplateTokenRenderer - { - readonly ConsoleTheme _theme; - readonly string _text; + readonly ConsoleTheme _theme; + readonly string _text; - public TextTokenRenderer(ConsoleTheme theme, string text) - { + public TextTokenRenderer(ConsoleTheme theme, string text) + { _theme = theme; _text = text; } - public override void Render(LogEvent logEvent, TextWriter output) - { + public override void Render(LogEvent logEvent, TextWriter output) + { var _ = 0; using (_theme.Apply(output, ConsoleThemeStyle.TertiaryText, ref _)) output.Write(_text); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/TimestampTokenRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/TimestampTokenRenderer.cs index bc5f000..7c4de83 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/TimestampTokenRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/TimestampTokenRenderer.cs @@ -20,23 +20,23 @@ using Serilog.Sinks.SystemConsole.Rendering; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Output +namespace Serilog.Sinks.SystemConsole.Output; + +class TimestampTokenRenderer : OutputTemplateTokenRenderer { - class TimestampTokenRenderer : OutputTemplateTokenRenderer - { - readonly ConsoleTheme _theme; - readonly PropertyToken _token; - readonly IFormatProvider? _formatProvider; + readonly ConsoleTheme _theme; + readonly PropertyToken _token; + readonly IFormatProvider? _formatProvider; - public TimestampTokenRenderer(ConsoleTheme theme, PropertyToken token, IFormatProvider? formatProvider) - { + public TimestampTokenRenderer(ConsoleTheme theme, PropertyToken token, IFormatProvider? formatProvider) + { _theme = theme; _token = token; _formatProvider = formatProvider; } - public override void Render(LogEvent logEvent, TextWriter output) - { + public override void Render(LogEvent logEvent, TextWriter output) + { var sv = new DateTimeOffsetValue(logEvent.Timestamp); var _ = 0; @@ -56,23 +56,23 @@ public override void Render(LogEvent logEvent, TextWriter output) } } - readonly struct DateTimeOffsetValue + readonly struct DateTimeOffsetValue + { + public DateTimeOffsetValue(DateTimeOffset value) { - public DateTimeOffsetValue(DateTimeOffset value) - { Value = value; } - public DateTimeOffset Value { get; } + public DateTimeOffset Value { get; } - public void Render(TextWriter output, string? format = null, IFormatProvider? formatProvider = null) + public void Render(TextWriter output, string? format = null, IFormatProvider? formatProvider = null) + { + var custom = (ICustomFormatter?)formatProvider?.GetFormat(typeof(ICustomFormatter)); + if (custom != null) { - var custom = (ICustomFormatter?)formatProvider?.GetFormat(typeof(ICustomFormatter)); - if (custom != null) - { - output.Write(custom.Format(format, Value, formatProvider)); - return; - } + output.Write(custom.Format(format, Value, formatProvider)); + return; + } #if FEATURE_SPAN Span buffer = stackalloc char[32]; @@ -81,9 +81,8 @@ public void Render(TextWriter output, string? format = null, IFormatProvider? fo else output.Write(Value.ToString(format, formatProvider ?? CultureInfo.InvariantCulture)); #else - output.Write(Value.ToString(format, formatProvider ?? CultureInfo.InvariantCulture)); + output.Write(Value.ToString(format, formatProvider ?? CultureInfo.InvariantCulture)); #endif - } } } -} +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Platform/WindowsConsole.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Platform/WindowsConsole.cs index fce3ecf..38b8f50 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Platform/WindowsConsole.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Platform/WindowsConsole.cs @@ -15,37 +15,36 @@ using System; using System.Runtime.InteropServices; -namespace Serilog.Sinks.SystemConsole.Platform +namespace Serilog.Sinks.SystemConsole.Platform; + +static class WindowsConsole { - static class WindowsConsole + public static void EnableVirtualTerminalProcessing() { - public static void EnableVirtualTerminalProcessing() - { #if RUNTIME_INFORMATION - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - return; + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return; #else if (Environment.OSVersion.Platform != PlatformID.Win32NT) return; #endif - var stdout = GetStdHandle(StandardOutputHandleId); - if (stdout != (IntPtr)InvalidHandleValue && GetConsoleMode(stdout, out var mode)) - { - SetConsoleMode(stdout, mode | EnableVirtualTerminalProcessingMode); - } + var stdout = GetStdHandle(StandardOutputHandleId); + if (stdout != (IntPtr)InvalidHandleValue && GetConsoleMode(stdout, out var mode)) + { + SetConsoleMode(stdout, mode | EnableVirtualTerminalProcessingMode); } + } - const int StandardOutputHandleId = -11; - const uint EnableVirtualTerminalProcessingMode = 4; - const long InvalidHandleValue = -1; + const int StandardOutputHandleId = -11; + const uint EnableVirtualTerminalProcessingMode = 4; + const long InvalidHandleValue = -1; - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr GetStdHandle(int handleId); + [DllImport("kernel32.dll", SetLastError = true)] + static extern IntPtr GetStdHandle(int handleId); - [DllImport("kernel32.dll", SetLastError = true)] - static extern bool GetConsoleMode(IntPtr handle, out uint mode); + [DllImport("kernel32.dll", SetLastError = true)] + static extern bool GetConsoleMode(IntPtr handle, out uint mode); - [DllImport("kernel32.dll", SetLastError = true)] - static extern bool SetConsoleMode(IntPtr handle, uint mode); - } -} + [DllImport("kernel32.dll", SetLastError = true)] + static extern bool SetConsoleMode(IntPtr handle, uint mode); +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/AlignmentExtensions.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/AlignmentExtensions.cs index 6964274..800442f 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/AlignmentExtensions.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/AlignmentExtensions.cs @@ -14,13 +14,12 @@ using Serilog.Parsing; -namespace Serilog.Sinks.SystemConsole.Rendering +namespace Serilog.Sinks.SystemConsole.Rendering; + +static class AlignmentExtensions { - static class AlignmentExtensions + public static Alignment Widen(this Alignment alignment, int amount) { - public static Alignment Widen(this Alignment alignment, int amount) - { return new Alignment(alignment.Direction, alignment.Width + amount); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/Casing.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/Casing.cs index 66ce179..2568b54 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/Casing.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/Casing.cs @@ -12,19 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Serilog.Sinks.SystemConsole.Rendering +namespace Serilog.Sinks.SystemConsole.Rendering; + +static class Casing { - static class Casing + /// + /// Apply upper or lower casing to when is provided. + /// Returns when no or invalid format provided. + /// + /// Provided string for formatting. + /// Format string. + /// The provided with formatting applied. + public static string Format(string value, string? format = null) { - /// - /// Apply upper or lower casing to when is provided. - /// Returns when no or invalid format provided. - /// - /// Provided string for formatting. - /// Format string. - /// The provided with formatting applied. - public static string Format(string value, string? format = null) - { switch (format) { case "u": @@ -35,5 +35,4 @@ public static string Format(string value, string? format = null) return value; } } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/Padding.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/Padding.cs index 12d2595..fb4a6ea 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/Padding.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/Padding.cs @@ -15,20 +15,20 @@ using System.IO; using Serilog.Parsing; -namespace Serilog.Sinks.SystemConsole.Rendering +namespace Serilog.Sinks.SystemConsole.Rendering; + +static class Padding { - static class Padding + static readonly char[] PaddingChars = new string(' ', 80).ToCharArray(); + + /// + /// Writes the provided value to the output, applying direction-based padding when is provided. + /// + /// Output object to write result. + /// Provided value. + /// The alignment settings to apply when rendering . + public static void Apply(TextWriter output, string value, Alignment? alignment) { - static readonly char[] PaddingChars = new string(' ', 80).ToCharArray(); - - /// - /// Writes the provided value to the output, applying direction-based padding when is provided. - /// - /// Output object to write result. - /// Provided value. - /// The alignment settings to apply when rendering . - public static void Apply(TextWriter output, string value, Alignment? alignment) - { if (alignment is null || value.Length >= alignment.Value.Width) { output.Write(value); @@ -52,5 +52,4 @@ public static void Apply(TextWriter output, string value, Alignment? alignment) if (alignment.Value.Direction == AlignmentDirection.Right) output.Write(value); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/ThemedMessageTemplateRenderer.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/ThemedMessageTemplateRenderer.cs index a299520..eeca581 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/ThemedMessageTemplateRenderer.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Rendering/ThemedMessageTemplateRenderer.cs @@ -20,26 +20,26 @@ using Serilog.Sinks.SystemConsole.Formatting; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Rendering +namespace Serilog.Sinks.SystemConsole.Rendering; + +class ThemedMessageTemplateRenderer { - class ThemedMessageTemplateRenderer + readonly ConsoleTheme _theme; + readonly ThemedValueFormatter _valueFormatter; + readonly bool _isLiteral; + static readonly ConsoleTheme NoTheme = new EmptyConsoleTheme(); + readonly ThemedValueFormatter _unthemedValueFormatter; + + public ThemedMessageTemplateRenderer(ConsoleTheme theme, ThemedValueFormatter valueFormatter, bool isLiteral) { - readonly ConsoleTheme _theme; - readonly ThemedValueFormatter _valueFormatter; - readonly bool _isLiteral; - static readonly ConsoleTheme NoTheme = new EmptyConsoleTheme(); - readonly ThemedValueFormatter _unthemedValueFormatter; - - public ThemedMessageTemplateRenderer(ConsoleTheme theme, ThemedValueFormatter valueFormatter, bool isLiteral) - { _theme = theme ?? throw new ArgumentNullException(nameof(theme)); _valueFormatter = valueFormatter; _isLiteral = isLiteral; _unthemedValueFormatter = valueFormatter.SwitchTheme(NoTheme); } - public int Render(MessageTemplate template, IReadOnlyDictionary properties, TextWriter output) - { + public int Render(MessageTemplate template, IReadOnlyDictionary properties, TextWriter output) + { var count = 0; foreach (var token in template.Tokens) { @@ -56,16 +56,16 @@ public int Render(MessageTemplate template, IReadOnlyDictionary properties, TextWriter output) - { + int RenderPropertyToken(PropertyToken pt, IReadOnlyDictionary properties, TextWriter output) + { if (!properties.TryGetValue(pt.PropertyName, out var propertyValue)) { var count = 0; @@ -100,8 +100,8 @@ int RenderPropertyToken(PropertyToken pt, IReadOnlyDictionary +/// A console theme using the ANSI terminal escape sequences. Recommended +/// for Linux and Windows 10+. +/// +public class AnsiConsoleTheme : ConsoleTheme { /// - /// A console theme using the ANSI terminal escape sequences. Recommended - /// for Linux and Windows 10+. + /// A 256-color theme along the lines of Visual Studio Code. /// - public class AnsiConsoleTheme : ConsoleTheme - { - /// - /// A 256-color theme along the lines of Visual Studio Code. - /// - public static AnsiConsoleTheme Code { get; } = AnsiConsoleThemes.Code; + public static AnsiConsoleTheme Code { get; } = AnsiConsoleThemes.Code; - /// - /// A theme using only gray, black and white. - /// - public static AnsiConsoleTheme Grayscale { get; } = AnsiConsoleThemes.Grayscale; + /// + /// A theme using only gray, black and white. + /// + public static AnsiConsoleTheme Grayscale { get; } = AnsiConsoleThemes.Grayscale; - /// - /// A theme in the style of the original Serilog.Sinks.Literate. - /// - public static AnsiConsoleTheme Literate { get; } = AnsiConsoleThemes.Literate; + /// + /// A theme in the style of the original Serilog.Sinks.Literate. + /// + public static AnsiConsoleTheme Literate { get; } = AnsiConsoleThemes.Literate; - /// - /// A theme in the style of the original Serilog.Sinks.Literate using only standard 16 terminal colors that will work on light backgrounds. - /// - public static AnsiConsoleTheme Sixteen { get; } = AnsiConsoleThemes.Sixteen; + /// + /// A theme in the style of the original Serilog.Sinks.Literate using only standard 16 terminal colors that will work on light backgrounds. + /// + public static AnsiConsoleTheme Sixteen { get; } = AnsiConsoleThemes.Sixteen; - readonly IReadOnlyDictionary _styles; - const string AnsiStyleReset = "\x1b[0m"; + readonly IReadOnlyDictionary _styles; + const string AnsiStyleReset = "\x1b[0m"; - /// - /// Construct a theme given a set of styles. - /// - /// Styles to apply within the theme. - /// When is null - public AnsiConsoleTheme(IReadOnlyDictionary styles) - { + /// + /// Construct a theme given a set of styles. + /// + /// Styles to apply within the theme. + /// When is null + public AnsiConsoleTheme(IReadOnlyDictionary styles) + { if (styles is null) throw new ArgumentNullException(nameof(styles)); _styles = styles.ToDictionary(kv => kv.Key, kv => kv.Value); } - /// - public override bool CanBuffer => true; + /// + public override bool CanBuffer => true; - /// - protected override int ResetCharCount { get; } = AnsiStyleReset.Length; + /// + protected override int ResetCharCount { get; } = AnsiStyleReset.Length; - /// - public override int Set(TextWriter output, ConsoleThemeStyle style) - { + /// + public override int Set(TextWriter output, ConsoleThemeStyle style) + { if (_styles.TryGetValue(style, out var ansiStyle)) { output.Write(ansiStyle); @@ -76,10 +76,9 @@ public override int Set(TextWriter output, ConsoleThemeStyle style) return 0; } - /// - public override void Reset(TextWriter output) - { + /// + public override void Reset(TextWriter output) + { output.Write(AnsiStyleReset); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/AnsiConsoleThemes.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/AnsiConsoleThemes.cs index 1728aa0..78bfb9b 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/AnsiConsoleThemes.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/AnsiConsoleThemes.cs @@ -14,92 +14,91 @@ using System.Collections.Generic; -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +static class AnsiConsoleThemes { - static class AnsiConsoleThemes - { - public static AnsiConsoleTheme Literate { get; } = new AnsiConsoleTheme( - new Dictionary - { - [ConsoleThemeStyle.Text] = "\x1b[38;5;0015m", - [ConsoleThemeStyle.SecondaryText] = "\x1b[38;5;0007m", - [ConsoleThemeStyle.TertiaryText] = "\x1b[38;5;0008m", - [ConsoleThemeStyle.Invalid] = "\x1b[38;5;0011m", - [ConsoleThemeStyle.Null] = "\x1b[38;5;0027m", - [ConsoleThemeStyle.Name] = "\x1b[38;5;0007m", - [ConsoleThemeStyle.String] = "\x1b[38;5;0045m", - [ConsoleThemeStyle.Number] = "\x1b[38;5;0200m", - [ConsoleThemeStyle.Boolean] = "\x1b[38;5;0027m", - [ConsoleThemeStyle.Scalar] = "\x1b[38;5;0085m", - [ConsoleThemeStyle.LevelVerbose] = "\x1b[38;5;0007m", - [ConsoleThemeStyle.LevelDebug] = "\x1b[38;5;0007m", - [ConsoleThemeStyle.LevelInformation] = "\x1b[38;5;0015m", - [ConsoleThemeStyle.LevelWarning] = "\x1b[38;5;0011m", - [ConsoleThemeStyle.LevelError] = "\x1b[38;5;0015m\x1b[48;5;0196m", - [ConsoleThemeStyle.LevelFatal] = "\x1b[38;5;0015m\x1b[48;5;0196m", - }); + public static AnsiConsoleTheme Literate { get; } = new AnsiConsoleTheme( + new Dictionary + { + [ConsoleThemeStyle.Text] = "\x1b[38;5;0015m", + [ConsoleThemeStyle.SecondaryText] = "\x1b[38;5;0007m", + [ConsoleThemeStyle.TertiaryText] = "\x1b[38;5;0008m", + [ConsoleThemeStyle.Invalid] = "\x1b[38;5;0011m", + [ConsoleThemeStyle.Null] = "\x1b[38;5;0027m", + [ConsoleThemeStyle.Name] = "\x1b[38;5;0007m", + [ConsoleThemeStyle.String] = "\x1b[38;5;0045m", + [ConsoleThemeStyle.Number] = "\x1b[38;5;0200m", + [ConsoleThemeStyle.Boolean] = "\x1b[38;5;0027m", + [ConsoleThemeStyle.Scalar] = "\x1b[38;5;0085m", + [ConsoleThemeStyle.LevelVerbose] = "\x1b[38;5;0007m", + [ConsoleThemeStyle.LevelDebug] = "\x1b[38;5;0007m", + [ConsoleThemeStyle.LevelInformation] = "\x1b[38;5;0015m", + [ConsoleThemeStyle.LevelWarning] = "\x1b[38;5;0011m", + [ConsoleThemeStyle.LevelError] = "\x1b[38;5;0015m\x1b[48;5;0196m", + [ConsoleThemeStyle.LevelFatal] = "\x1b[38;5;0015m\x1b[48;5;0196m", + }); - public static AnsiConsoleTheme Grayscale { get; } = new AnsiConsoleTheme( - new Dictionary - { - [ConsoleThemeStyle.Text] = "\x1b[37;1m", - [ConsoleThemeStyle.SecondaryText] = "\x1b[37m", - [ConsoleThemeStyle.TertiaryText] = "\x1b[30;1m", - [ConsoleThemeStyle.Invalid] = "\x1b[37;1m\x1b[47m", - [ConsoleThemeStyle.Null] = "\x1b[1m\x1b[37;1m", - [ConsoleThemeStyle.Name] = "\x1b[37m", - [ConsoleThemeStyle.String] = "\x1b[1m\x1b[37;1m", - [ConsoleThemeStyle.Number] = "\x1b[1m\x1b[37;1m", - [ConsoleThemeStyle.Boolean] = "\x1b[1m\x1b[37;1m", - [ConsoleThemeStyle.Scalar] = "\x1b[1m\x1b[37;1m", - [ConsoleThemeStyle.LevelVerbose] = "\x1b[30;1m", - [ConsoleThemeStyle.LevelDebug] = "\x1b[30;1m", - [ConsoleThemeStyle.LevelInformation] = "\x1b[37;1m", - [ConsoleThemeStyle.LevelWarning] = "\x1b[37;1m\x1b[47m", - [ConsoleThemeStyle.LevelError] = "\x1b[30m\x1b[47m", - [ConsoleThemeStyle.LevelFatal] = "\x1b[30m\x1b[47m", - }); + public static AnsiConsoleTheme Grayscale { get; } = new AnsiConsoleTheme( + new Dictionary + { + [ConsoleThemeStyle.Text] = "\x1b[37;1m", + [ConsoleThemeStyle.SecondaryText] = "\x1b[37m", + [ConsoleThemeStyle.TertiaryText] = "\x1b[30;1m", + [ConsoleThemeStyle.Invalid] = "\x1b[37;1m\x1b[47m", + [ConsoleThemeStyle.Null] = "\x1b[1m\x1b[37;1m", + [ConsoleThemeStyle.Name] = "\x1b[37m", + [ConsoleThemeStyle.String] = "\x1b[1m\x1b[37;1m", + [ConsoleThemeStyle.Number] = "\x1b[1m\x1b[37;1m", + [ConsoleThemeStyle.Boolean] = "\x1b[1m\x1b[37;1m", + [ConsoleThemeStyle.Scalar] = "\x1b[1m\x1b[37;1m", + [ConsoleThemeStyle.LevelVerbose] = "\x1b[30;1m", + [ConsoleThemeStyle.LevelDebug] = "\x1b[30;1m", + [ConsoleThemeStyle.LevelInformation] = "\x1b[37;1m", + [ConsoleThemeStyle.LevelWarning] = "\x1b[37;1m\x1b[47m", + [ConsoleThemeStyle.LevelError] = "\x1b[30m\x1b[47m", + [ConsoleThemeStyle.LevelFatal] = "\x1b[30m\x1b[47m", + }); - public static AnsiConsoleTheme Code { get; } = new AnsiConsoleTheme( - new Dictionary - { - [ConsoleThemeStyle.Text] = "\x1b[38;5;0253m", - [ConsoleThemeStyle.SecondaryText] = "\x1b[38;5;0246m", - [ConsoleThemeStyle.TertiaryText] = "\x1b[38;5;0242m", - [ConsoleThemeStyle.Invalid] = "\x1b[33;1m", - [ConsoleThemeStyle.Null] = "\x1b[38;5;0038m", - [ConsoleThemeStyle.Name] = "\x1b[38;5;0081m", - [ConsoleThemeStyle.String] = "\x1b[38;5;0216m", - [ConsoleThemeStyle.Number] = "\x1b[38;5;151m", - [ConsoleThemeStyle.Boolean] = "\x1b[38;5;0038m", - [ConsoleThemeStyle.Scalar] = "\x1b[38;5;0079m", - [ConsoleThemeStyle.LevelVerbose] = "\x1b[37m", - [ConsoleThemeStyle.LevelDebug] = "\x1b[37m", - [ConsoleThemeStyle.LevelInformation] = "\x1b[37;1m", - [ConsoleThemeStyle.LevelWarning] = "\x1b[38;5;0229m", - [ConsoleThemeStyle.LevelError] = "\x1b[38;5;0197m\x1b[48;5;0238m", - [ConsoleThemeStyle.LevelFatal] = "\x1b[38;5;0197m\x1b[48;5;0238m", - }); + public static AnsiConsoleTheme Code { get; } = new AnsiConsoleTheme( + new Dictionary + { + [ConsoleThemeStyle.Text] = "\x1b[38;5;0253m", + [ConsoleThemeStyle.SecondaryText] = "\x1b[38;5;0246m", + [ConsoleThemeStyle.TertiaryText] = "\x1b[38;5;0242m", + [ConsoleThemeStyle.Invalid] = "\x1b[33;1m", + [ConsoleThemeStyle.Null] = "\x1b[38;5;0038m", + [ConsoleThemeStyle.Name] = "\x1b[38;5;0081m", + [ConsoleThemeStyle.String] = "\x1b[38;5;0216m", + [ConsoleThemeStyle.Number] = "\x1b[38;5;151m", + [ConsoleThemeStyle.Boolean] = "\x1b[38;5;0038m", + [ConsoleThemeStyle.Scalar] = "\x1b[38;5;0079m", + [ConsoleThemeStyle.LevelVerbose] = "\x1b[37m", + [ConsoleThemeStyle.LevelDebug] = "\x1b[37m", + [ConsoleThemeStyle.LevelInformation] = "\x1b[37;1m", + [ConsoleThemeStyle.LevelWarning] = "\x1b[38;5;0229m", + [ConsoleThemeStyle.LevelError] = "\x1b[38;5;0197m\x1b[48;5;0238m", + [ConsoleThemeStyle.LevelFatal] = "\x1b[38;5;0197m\x1b[48;5;0238m", + }); - public static AnsiConsoleTheme Sixteen { get; } = new AnsiConsoleTheme( - new Dictionary - { - [ConsoleThemeStyle.Text] = AnsiEscapeSequence.Unthemed, - [ConsoleThemeStyle.SecondaryText] = AnsiEscapeSequence.Unthemed, - [ConsoleThemeStyle.TertiaryText] = AnsiEscapeSequence.Unthemed, - [ConsoleThemeStyle.Invalid] = AnsiEscapeSequence.Yellow, - [ConsoleThemeStyle.Null] = AnsiEscapeSequence.Blue, - [ConsoleThemeStyle.Name] = AnsiEscapeSequence.Unthemed, - [ConsoleThemeStyle.String] = AnsiEscapeSequence.Cyan, - [ConsoleThemeStyle.Number] = AnsiEscapeSequence.Magenta, - [ConsoleThemeStyle.Boolean] = AnsiEscapeSequence.Blue, - [ConsoleThemeStyle.Scalar] = AnsiEscapeSequence.Green, - [ConsoleThemeStyle.LevelVerbose] = AnsiEscapeSequence.Unthemed, - [ConsoleThemeStyle.LevelDebug] = AnsiEscapeSequence.Bold, - [ConsoleThemeStyle.LevelInformation] = AnsiEscapeSequence.BrightCyan, - [ConsoleThemeStyle.LevelWarning] = AnsiEscapeSequence.BrightYellow, - [ConsoleThemeStyle.LevelError] = AnsiEscapeSequence.BrightRed, - [ConsoleThemeStyle.LevelFatal] = AnsiEscapeSequence.BrightRed, - }); - } -} + public static AnsiConsoleTheme Sixteen { get; } = new AnsiConsoleTheme( + new Dictionary + { + [ConsoleThemeStyle.Text] = AnsiEscapeSequence.Unthemed, + [ConsoleThemeStyle.SecondaryText] = AnsiEscapeSequence.Unthemed, + [ConsoleThemeStyle.TertiaryText] = AnsiEscapeSequence.Unthemed, + [ConsoleThemeStyle.Invalid] = AnsiEscapeSequence.Yellow, + [ConsoleThemeStyle.Null] = AnsiEscapeSequence.Blue, + [ConsoleThemeStyle.Name] = AnsiEscapeSequence.Unthemed, + [ConsoleThemeStyle.String] = AnsiEscapeSequence.Cyan, + [ConsoleThemeStyle.Number] = AnsiEscapeSequence.Magenta, + [ConsoleThemeStyle.Boolean] = AnsiEscapeSequence.Blue, + [ConsoleThemeStyle.Scalar] = AnsiEscapeSequence.Green, + [ConsoleThemeStyle.LevelVerbose] = AnsiEscapeSequence.Unthemed, + [ConsoleThemeStyle.LevelDebug] = AnsiEscapeSequence.Bold, + [ConsoleThemeStyle.LevelInformation] = AnsiEscapeSequence.BrightCyan, + [ConsoleThemeStyle.LevelWarning] = AnsiEscapeSequence.BrightYellow, + [ConsoleThemeStyle.LevelError] = AnsiEscapeSequence.BrightRed, + [ConsoleThemeStyle.LevelFatal] = AnsiEscapeSequence.BrightRed, + }); +} \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/AnsiEscapeSequence.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/AnsiEscapeSequence.cs index 2512190..2e29d53 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/AnsiEscapeSequence.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/AnsiEscapeSequence.cs @@ -12,30 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +static class AnsiEscapeSequence { - static class AnsiEscapeSequence - { - public const string Unthemed = ""; - public const string Reset = "\x1b[0m"; - public const string Bold = "\x1b[1m"; + public const string Unthemed = ""; + public const string Reset = "\x1b[0m"; + public const string Bold = "\x1b[1m"; - public const string Black = "\x1b[30m"; - public const string Red = "\x1b[31m"; - public const string Green = "\x1b[32m"; - public const string Yellow = "\x1b[33m"; - public const string Blue = "\x1b[34m"; - public const string Magenta = "\x1b[35m"; - public const string Cyan = "\x1b[36m"; - public const string White = "\x1b[37m"; + public const string Black = "\x1b[30m"; + public const string Red = "\x1b[31m"; + public const string Green = "\x1b[32m"; + public const string Yellow = "\x1b[33m"; + public const string Blue = "\x1b[34m"; + public const string Magenta = "\x1b[35m"; + public const string Cyan = "\x1b[36m"; + public const string White = "\x1b[37m"; - public const string BrightBlack = "\x1b[30;1m"; - public const string BrightRed = "\x1b[31;1m"; - public const string BrightGreen = "\x1b[32;1m"; - public const string BrightYellow = "\x1b[33;1m"; - public const string BrightBlue = "\x1b[34;1m"; - public const string BrightMagenta = "\x1b[35;1m"; - public const string BrightCyan = "\x1b[36;1m"; - public const string BrightWhite = "\x1b[37;1m"; - } + public const string BrightBlack = "\x1b[30;1m"; + public const string BrightRed = "\x1b[31;1m"; + public const string BrightGreen = "\x1b[32;1m"; + public const string BrightYellow = "\x1b[33;1m"; + public const string BrightBlue = "\x1b[34;1m"; + public const string BrightMagenta = "\x1b[35;1m"; + public const string BrightCyan = "\x1b[36;1m"; + public const string BrightWhite = "\x1b[37;1m"; } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/ConsoleTheme.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/ConsoleTheme.cs index b3921bf..d4c81f1 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/ConsoleTheme.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/ConsoleTheme.cs @@ -14,49 +14,48 @@ using System.IO; -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +/// +/// The base class for styled terminal output. +/// +public abstract class ConsoleTheme { /// - /// The base class for styled terminal output. + /// No styling applied. + /// + public static ConsoleTheme None { get; } = new EmptyConsoleTheme(); + + /// + /// True if styling applied by the theme is written into the output, and can thus be + /// buffered and measured. + /// + public abstract bool CanBuffer { get; } + + /// + /// Begin a span of text in the specified . /// - public abstract class ConsoleTheme + /// Output destination. + /// Style to apply. + /// The number of characters written to . + public abstract int Set(TextWriter output, ConsoleThemeStyle style); + + /// + /// Reset the output to un-styled colors. + /// + /// Output destination. + public abstract void Reset(TextWriter output); + + /// + /// The number of characters written by the method. + /// + protected abstract int ResetCharCount { get; } + + internal StyleReset Apply(TextWriter output, ConsoleThemeStyle style, ref int invisibleCharacterCount) { - /// - /// No styling applied. - /// - public static ConsoleTheme None { get; } = new EmptyConsoleTheme(); - - /// - /// True if styling applied by the theme is written into the output, and can thus be - /// buffered and measured. - /// - public abstract bool CanBuffer { get; } - - /// - /// Begin a span of text in the specified . - /// - /// Output destination. - /// Style to apply. - /// The number of characters written to . - public abstract int Set(TextWriter output, ConsoleThemeStyle style); - - /// - /// Reset the output to un-styled colors. - /// - /// Output destination. - public abstract void Reset(TextWriter output); - - /// - /// The number of characters written by the method. - /// - protected abstract int ResetCharCount { get; } - - internal StyleReset Apply(TextWriter output, ConsoleThemeStyle style, ref int invisibleCharacterCount) - { invisibleCharacterCount += Set(output, style); invisibleCharacterCount += ResetCharCount; return new StyleReset(this, output); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/ConsoleThemeStyle.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/ConsoleThemeStyle.cs index 69d231f..5c8ff63 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/ConsoleThemeStyle.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/ConsoleThemeStyle.cs @@ -15,100 +15,99 @@ using System; using System.ComponentModel; -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +/// +/// Elements styled by a console theme. +/// +public enum ConsoleThemeStyle { /// - /// Elements styled by a console theme. - /// - public enum ConsoleThemeStyle - { - /// - /// Prominent text, generally content within an event's message. - /// - Text, - - /// - /// Boilerplate text, for example items specified in an output template. - /// - SecondaryText, - - /// - /// De-emphasized text, for example literal text in output templates and - /// punctuation used when writing structured data. - /// - TertiaryText, - - /// - /// Output demonstrating some kind of configuration issue, e.g. an invalid - /// message template token. - /// - Invalid, - - /// - /// The built-in value. - /// - Null, - - /// - /// Property and type names. - /// - Name, - - /// - /// Strings. - /// - String, - - /// - /// Numbers. - /// - Number, - - /// - /// values. - /// - Boolean, - - /// - /// All other scalar values, e.g. instances. - /// - Scalar, - - /// - /// Unrecognized literal values, e.g. instances. - /// - [Obsolete("Use ConsoleThemeStyle.Scalar instead")] - [EditorBrowsable(EditorBrowsableState.Never)] - Object = Scalar, - - /// - /// Level indicator. - /// - LevelVerbose, - - /// - /// Level indicator. - /// - LevelDebug, - - /// - /// Level indicator. - /// - LevelInformation, - - /// - /// Level indicator. - /// - LevelWarning, - - /// - /// Level indicator. - /// - LevelError, - - /// - /// Level indicator. - /// - LevelFatal, - } + /// Prominent text, generally content within an event's message. + /// + Text, + + /// + /// Boilerplate text, for example items specified in an output template. + /// + SecondaryText, + + /// + /// De-emphasized text, for example literal text in output templates and + /// punctuation used when writing structured data. + /// + TertiaryText, + + /// + /// Output demonstrating some kind of configuration issue, e.g. an invalid + /// message template token. + /// + Invalid, + + /// + /// The built-in value. + /// + Null, + + /// + /// Property and type names. + /// + Name, + + /// + /// Strings. + /// + String, + + /// + /// Numbers. + /// + Number, + + /// + /// values. + /// + Boolean, + + /// + /// All other scalar values, e.g. instances. + /// + Scalar, + + /// + /// Unrecognized literal values, e.g. instances. + /// + [Obsolete("Use ConsoleThemeStyle.Scalar instead")] + [EditorBrowsable(EditorBrowsableState.Never)] + Object = Scalar, + + /// + /// Level indicator. + /// + LevelVerbose, + + /// + /// Level indicator. + /// + LevelDebug, + + /// + /// Level indicator. + /// + LevelInformation, + + /// + /// Level indicator. + /// + LevelWarning, + + /// + /// Level indicator. + /// + LevelError, + + /// + /// Level indicator. + /// + LevelFatal, } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/EmptyConsoleTheme.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/EmptyConsoleTheme.cs index de74f8c..8454cc9 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/EmptyConsoleTheme.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/EmptyConsoleTheme.cs @@ -14,18 +14,17 @@ using System.IO; -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +class EmptyConsoleTheme : ConsoleTheme { - class EmptyConsoleTheme : ConsoleTheme - { - public override bool CanBuffer => true; + public override bool CanBuffer => true; - protected override int ResetCharCount { get; } + protected override int ResetCharCount { get; } - public override int Set(TextWriter output, ConsoleThemeStyle style) => 0; + public override int Set(TextWriter output, ConsoleThemeStyle style) => 0; - public override void Reset(TextWriter output) - { + public override void Reset(TextWriter output) + { } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/StyleReset.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/StyleReset.cs index a033161..49b11ce 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/StyleReset.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/StyleReset.cs @@ -15,22 +15,21 @@ using System; using System.IO; -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +struct StyleReset : IDisposable { - struct StyleReset : IDisposable - { - readonly ConsoleTheme _theme; - readonly TextWriter _output; + readonly ConsoleTheme _theme; + readonly TextWriter _output; - public StyleReset(ConsoleTheme theme, TextWriter output) - { + public StyleReset(ConsoleTheme theme, TextWriter output) + { _theme = theme; _output = output; } - public void Dispose() - { + public void Dispose() + { _theme.Reset(_output); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleTheme.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleTheme.cs index a4518c8..abfe02c 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleTheme.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleTheme.cs @@ -17,52 +17,52 @@ using System.IO; using System.Linq; -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +/// +/// A console theme using the styling facilities of the class. Recommended +/// for Windows versions prior to Windows 10. +/// +public class SystemConsoleTheme : ConsoleTheme { /// - /// A console theme using the styling facilities of the class. Recommended - /// for Windows versions prior to Windows 10. + /// A theme using only gray, black and white. /// - public class SystemConsoleTheme : ConsoleTheme - { - /// - /// A theme using only gray, black and white. - /// - public static SystemConsoleTheme Grayscale { get; } = SystemConsoleThemes.Grayscale; + public static SystemConsoleTheme Grayscale { get; } = SystemConsoleThemes.Grayscale; - /// - /// A theme in the style of the original Serilog.Sinks.Literate. - /// - public static SystemConsoleTheme Literate { get; } = SystemConsoleThemes.Literate; + /// + /// A theme in the style of the original Serilog.Sinks.Literate. + /// + public static SystemConsoleTheme Literate { get; } = SystemConsoleThemes.Literate; - /// - /// A theme based on the original Serilog "colored console" sink. - /// - public static SystemConsoleTheme Colored { get; } = SystemConsoleThemes.Colored; + /// + /// A theme based on the original Serilog "colored console" sink. + /// + public static SystemConsoleTheme Colored { get; } = SystemConsoleThemes.Colored; - /// - /// Construct a theme given a set of styles. - /// - /// Styles to apply within the theme. - /// When is null - public SystemConsoleTheme(IReadOnlyDictionary styles) - { + /// + /// Construct a theme given a set of styles. + /// + /// Styles to apply within the theme. + /// When is null + public SystemConsoleTheme(IReadOnlyDictionary styles) + { if (styles is null) throw new ArgumentNullException(nameof(styles)); Styles = styles.ToDictionary(kv => kv.Key, kv => kv.Value); } - /// - public IReadOnlyDictionary Styles { get; } + /// + public IReadOnlyDictionary Styles { get; } - /// - public override bool CanBuffer => false; + /// + public override bool CanBuffer => false; - /// - protected override int ResetCharCount { get; } + /// + protected override int ResetCharCount { get; } - /// - public override int Set(TextWriter output, ConsoleThemeStyle style) - { + /// + public override int Set(TextWriter output, ConsoleThemeStyle style) + { if (Styles.TryGetValue(style, out var wcts)) { if (wcts.Foreground.HasValue) @@ -74,10 +74,9 @@ public override int Set(TextWriter output, ConsoleThemeStyle style) return 0; } - /// - public override void Reset(TextWriter output) - { + /// + public override void Reset(TextWriter output) + { Console.ResetColor(); } - } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleThemeStyle.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleThemeStyle.cs index 9cf64ce..3d5b05e 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleThemeStyle.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleThemeStyle.cs @@ -14,21 +14,20 @@ using System; -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +/// +/// Styling applied using the enumeration. +/// +public struct SystemConsoleThemeStyle { /// - /// Styling applied using the enumeration. + /// The foreground color to apply. /// - public struct SystemConsoleThemeStyle - { - /// - /// The foreground color to apply. - /// - public ConsoleColor? Foreground; + public ConsoleColor? Foreground; - /// - /// The background color to apply. - /// - public ConsoleColor? Background; - } + /// + /// The background color to apply. + /// + public ConsoleColor? Background; } \ No newline at end of file diff --git a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleThemes.cs b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleThemes.cs index 5e202f9..51bede7 100644 --- a/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleThemes.cs +++ b/src/Serilog.Sinks.Console/Sinks/SystemConsole/Themes/SystemConsoleThemes.cs @@ -15,71 +15,70 @@ using System; using System.Collections.Generic; -namespace Serilog.Sinks.SystemConsole.Themes +namespace Serilog.Sinks.SystemConsole.Themes; + +static class SystemConsoleThemes { - static class SystemConsoleThemes - { - public static SystemConsoleTheme Literate { get; } = new SystemConsoleTheme( - new Dictionary - { - [ConsoleThemeStyle.Text] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.SecondaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, - [ConsoleThemeStyle.TertiaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.Invalid] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Yellow }, - [ConsoleThemeStyle.Null] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Blue }, - [ConsoleThemeStyle.Name] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, - [ConsoleThemeStyle.String] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Cyan }, - [ConsoleThemeStyle.Number] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Magenta }, - [ConsoleThemeStyle.Boolean] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Blue }, - [ConsoleThemeStyle.Scalar] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Green }, - [ConsoleThemeStyle.LevelVerbose] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, - [ConsoleThemeStyle.LevelDebug] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, - [ConsoleThemeStyle.LevelInformation] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.LevelWarning] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Yellow }, - [ConsoleThemeStyle.LevelError] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Red }, - [ConsoleThemeStyle.LevelFatal] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Red }, - }); + public static SystemConsoleTheme Literate { get; } = new SystemConsoleTheme( + new Dictionary + { + [ConsoleThemeStyle.Text] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.SecondaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, + [ConsoleThemeStyle.TertiaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.Invalid] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Yellow }, + [ConsoleThemeStyle.Null] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Blue }, + [ConsoleThemeStyle.Name] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, + [ConsoleThemeStyle.String] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Cyan }, + [ConsoleThemeStyle.Number] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Magenta }, + [ConsoleThemeStyle.Boolean] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Blue }, + [ConsoleThemeStyle.Scalar] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Green }, + [ConsoleThemeStyle.LevelVerbose] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, + [ConsoleThemeStyle.LevelDebug] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, + [ConsoleThemeStyle.LevelInformation] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.LevelWarning] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Yellow }, + [ConsoleThemeStyle.LevelError] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Red }, + [ConsoleThemeStyle.LevelFatal] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Red }, + }); - public static SystemConsoleTheme Grayscale { get; } = new SystemConsoleTheme( - new Dictionary - { - [ConsoleThemeStyle.Text] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.SecondaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, - [ConsoleThemeStyle.TertiaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.Invalid] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.Null] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.Name] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, - [ConsoleThemeStyle.String] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.Number] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.Boolean] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.Scalar] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.LevelVerbose] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.LevelDebug] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.LevelInformation] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.LevelWarning] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.LevelError] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Black, Background = ConsoleColor.White }, - [ConsoleThemeStyle.LevelFatal] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Black, Background = ConsoleColor.White }, - }); + public static SystemConsoleTheme Grayscale { get; } = new SystemConsoleTheme( + new Dictionary + { + [ConsoleThemeStyle.Text] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.SecondaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, + [ConsoleThemeStyle.TertiaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.Invalid] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.Null] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.Name] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, + [ConsoleThemeStyle.String] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.Number] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.Boolean] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.Scalar] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.LevelVerbose] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.LevelDebug] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.LevelInformation] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.LevelWarning] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.LevelError] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Black, Background = ConsoleColor.White }, + [ConsoleThemeStyle.LevelFatal] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Black, Background = ConsoleColor.White }, + }); - public static SystemConsoleTheme Colored { get; } = new SystemConsoleTheme( - new Dictionary - { - [ConsoleThemeStyle.Text] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, - [ConsoleThemeStyle.SecondaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.TertiaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.Invalid] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Yellow }, - [ConsoleThemeStyle.Null] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.Name] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.String] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.Number] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.Boolean] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.Scalar] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, - [ConsoleThemeStyle.LevelVerbose] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray, Background = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.LevelDebug] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.DarkGray }, - [ConsoleThemeStyle.LevelInformation] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Blue }, - [ConsoleThemeStyle.LevelWarning] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray, Background = ConsoleColor.Yellow }, - [ConsoleThemeStyle.LevelError] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Red }, - [ConsoleThemeStyle.LevelFatal] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Red }, - }); - } -} + public static SystemConsoleTheme Colored { get; } = new SystemConsoleTheme( + new Dictionary + { + [ConsoleThemeStyle.Text] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray }, + [ConsoleThemeStyle.SecondaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.TertiaryText] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.Invalid] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Yellow }, + [ConsoleThemeStyle.Null] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.Name] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.String] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.Number] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.Boolean] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.Scalar] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White }, + [ConsoleThemeStyle.LevelVerbose] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.Gray, Background = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.LevelDebug] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.DarkGray }, + [ConsoleThemeStyle.LevelInformation] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Blue }, + [ConsoleThemeStyle.LevelWarning] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.DarkGray, Background = ConsoleColor.Yellow }, + [ConsoleThemeStyle.LevelError] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Red }, + [ConsoleThemeStyle.LevelFatal] = new SystemConsoleThemeStyle { Foreground = ConsoleColor.White, Background = ConsoleColor.Red }, + }); +} \ No newline at end of file diff --git a/test/Serilog.Sinks.Console.Tests/Configuration/ConsoleAuditLoggerConfigurationExtensionsTests.cs b/test/Serilog.Sinks.Console.Tests/Configuration/ConsoleAuditLoggerConfigurationExtensionsTests.cs index 1398128..f96fc8c 100644 --- a/test/Serilog.Sinks.Console.Tests/Configuration/ConsoleAuditLoggerConfigurationExtensionsTests.cs +++ b/test/Serilog.Sinks.Console.Tests/Configuration/ConsoleAuditLoggerConfigurationExtensionsTests.cs @@ -4,60 +4,59 @@ using Xunit; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.Console.Tests.Configuration +namespace Serilog.Sinks.Console.Tests.Configuration; + +[Collection("ConsoleSequentialTests")] +public class ConsoleAuditLoggerConfigurationExtensionsTests { - [Collection("ConsoleSequentialTests")] - public class ConsoleAuditLoggerConfigurationExtensionsTests + [Fact] + public void OutputFormattingIsIgnored() { - [Fact] - public void OutputFormattingIsIgnored() + using (var stream = new MemoryStream()) { - using (var stream = new MemoryStream()) - { - var sw = new StreamWriter(stream); + var sw = new StreamWriter(stream); - System.Console.SetOut(sw); - var config = new LoggerConfiguration() - .AuditTo.Console(theme: AnsiConsoleTheme.Literate, - applyThemeToRedirectedOutput: false); + System.Console.SetOut(sw); + var config = new LoggerConfiguration() + .AuditTo.Console(theme: AnsiConsoleTheme.Literate, + applyThemeToRedirectedOutput: false); - var logger = config.CreateLogger(); + var logger = config.CreateLogger(); - logger.Error("test"); - stream.Position = 0; + logger.Error("test"); + stream.Position = 0; - using (var streamReader = new StreamReader(stream)) - { - var result = streamReader.ReadToEnd(); - var controlCharacterCount = result.Count(c => Char.IsControl(c) && !Char.IsWhiteSpace(c)); - Assert.Equal(0, controlCharacterCount); - } + using (var streamReader = new StreamReader(stream)) + { + var result = streamReader.ReadToEnd(); + var controlCharacterCount = result.Count(c => Char.IsControl(c) && !Char.IsWhiteSpace(c)); + Assert.Equal(0, controlCharacterCount); } } + } - [Fact] - public void OutputFormattingIsPresent() + [Fact] + public void OutputFormattingIsPresent() + { + using (var stream = new MemoryStream()) { - using (var stream = new MemoryStream()) - { - var sw = new StreamWriter(stream); + var sw = new StreamWriter(stream); - System.Console.SetOut(sw); - var config = new LoggerConfiguration() - .AuditTo.Console(theme: AnsiConsoleTheme.Literate, - applyThemeToRedirectedOutput: true); + System.Console.SetOut(sw); + var config = new LoggerConfiguration() + .AuditTo.Console(theme: AnsiConsoleTheme.Literate, + applyThemeToRedirectedOutput: true); - var logger = config.CreateLogger(); + var logger = config.CreateLogger(); - logger.Error("test"); - stream.Position = 0; + logger.Error("test"); + stream.Position = 0; - using (var streamReader = new StreamReader(stream)) - { - var result = streamReader.ReadToEnd(); - var controlCharacterCount = result.Count(c => Char.IsControl(c) && !Char.IsWhiteSpace(c)); - Assert.NotEqual(0, controlCharacterCount); - } + using (var streamReader = new StreamReader(stream)) + { + var result = streamReader.ReadToEnd(); + var controlCharacterCount = result.Count(c => Char.IsControl(c) && !Char.IsWhiteSpace(c)); + Assert.NotEqual(0, controlCharacterCount); } } } diff --git a/test/Serilog.Sinks.Console.Tests/Configuration/ConsoleLoggerConfigurationExtensionsTests.cs b/test/Serilog.Sinks.Console.Tests/Configuration/ConsoleLoggerConfigurationExtensionsTests.cs index a66c82f..bc917d5 100644 --- a/test/Serilog.Sinks.Console.Tests/Configuration/ConsoleLoggerConfigurationExtensionsTests.cs +++ b/test/Serilog.Sinks.Console.Tests/Configuration/ConsoleLoggerConfigurationExtensionsTests.cs @@ -4,60 +4,59 @@ using Xunit; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.Console.Tests.Configuration +namespace Serilog.Sinks.Console.Tests.Configuration; + +[Collection("ConsoleSequentialTests")] +public class ConsoleLoggerConfigurationExtensionsTests { - [Collection("ConsoleSequentialTests")] - public class ConsoleLoggerConfigurationExtensionsTests + [Fact] + public void OutputFormattingIsIgnored() { - [Fact] - public void OutputFormattingIsIgnored() + using (var stream = new MemoryStream()) { - using (var stream = new MemoryStream()) - { - var sw = new StreamWriter(stream); + var sw = new StreamWriter(stream); - System.Console.SetOut(sw); - var config = new LoggerConfiguration() - .WriteTo.Console(theme: AnsiConsoleTheme.Literate, - applyThemeToRedirectedOutput: false); + System.Console.SetOut(sw); + var config = new LoggerConfiguration() + .WriteTo.Console(theme: AnsiConsoleTheme.Literate, + applyThemeToRedirectedOutput: false); - var logger = config.CreateLogger(); + var logger = config.CreateLogger(); - logger.Error("test"); - stream.Position = 0; + logger.Error("test"); + stream.Position = 0; - using (var streamReader = new StreamReader(stream)) - { - var result = streamReader.ReadToEnd(); - var controlCharacterCount = result.Count(c => Char.IsControl(c) && !Char.IsWhiteSpace(c)); - Assert.Equal(0, controlCharacterCount); - } + using (var streamReader = new StreamReader(stream)) + { + var result = streamReader.ReadToEnd(); + var controlCharacterCount = result.Count(c => Char.IsControl(c) && !Char.IsWhiteSpace(c)); + Assert.Equal(0, controlCharacterCount); } } + } - [Fact] - public void OutputFormattingIsPresent() + [Fact] + public void OutputFormattingIsPresent() + { + using (var stream = new MemoryStream()) { - using (var stream = new MemoryStream()) - { - var sw = new StreamWriter(stream); + var sw = new StreamWriter(stream); - System.Console.SetOut(sw); - var config = new LoggerConfiguration() - .WriteTo.Console(theme: AnsiConsoleTheme.Literate, - applyThemeToRedirectedOutput: true); + System.Console.SetOut(sw); + var config = new LoggerConfiguration() + .WriteTo.Console(theme: AnsiConsoleTheme.Literate, + applyThemeToRedirectedOutput: true); - var logger = config.CreateLogger(); + var logger = config.CreateLogger(); - logger.Error("test"); - stream.Position = 0; + logger.Error("test"); + stream.Position = 0; - using (var streamReader = new StreamReader(stream)) - { - var result = streamReader.ReadToEnd(); - var controlCharacterCount = result.Count(c => Char.IsControl(c) && !Char.IsWhiteSpace(c)); - Assert.NotEqual(0, controlCharacterCount); - } + using (var streamReader = new StreamReader(stream)) + { + var result = streamReader.ReadToEnd(); + var controlCharacterCount = result.Count(c => Char.IsControl(c) && !Char.IsWhiteSpace(c)); + Assert.NotEqual(0, controlCharacterCount); } } } diff --git a/test/Serilog.Sinks.Console.Tests/Formatting/ThemedDisplayValueFormatterTests.cs b/test/Serilog.Sinks.Console.Tests/Formatting/ThemedDisplayValueFormatterTests.cs index 2770069..f732fce 100644 --- a/test/Serilog.Sinks.Console.Tests/Formatting/ThemedDisplayValueFormatterTests.cs +++ b/test/Serilog.Sinks.Console.Tests/Formatting/ThemedDisplayValueFormatterTests.cs @@ -4,20 +4,19 @@ using Serilog.Sinks.SystemConsole.Themes; using Xunit; -namespace Serilog.Sinks.Console.Tests.Formatting +namespace Serilog.Sinks.Console.Tests.Formatting; + +public class ThemedDisplayValueFormatterTests { - public class ThemedDisplayValueFormatterTests + [Theory] + [InlineData("Hello", null, "\"Hello\"")] + [InlineData("Hello", "l", "Hello")] + public void StringFormattingIsApplied(string value, string format, string expected) { - [Theory] - [InlineData("Hello", null, "\"Hello\"")] - [InlineData("Hello", "l", "Hello")] - public void StringFormattingIsApplied(string value, string format, string expected) - { - var formatter = new ThemedDisplayValueFormatter(ConsoleTheme.None, null); - var sw = new StringWriter(); - formatter.FormatLiteralValue(new ScalarValue(value), sw, format); - var actual = sw.ToString(); - Assert.Equal(expected, actual); - } + var formatter = new ThemedDisplayValueFormatter(ConsoleTheme.None, null); + var sw = new StringWriter(); + formatter.FormatLiteralValue(new ScalarValue(value), sw, format); + var actual = sw.ToString(); + Assert.Equal(expected, actual); } -} +} \ No newline at end of file diff --git a/test/Serilog.Sinks.Console.Tests/Formatting/ThemedJsonValueFormatterTests.cs b/test/Serilog.Sinks.Console.Tests/Formatting/ThemedJsonValueFormatterTests.cs index 45a3814..aecdbe3 100644 --- a/test/Serilog.Sinks.Console.Tests/Formatting/ThemedJsonValueFormatterTests.cs +++ b/test/Serilog.Sinks.Console.Tests/Formatting/ThemedJsonValueFormatterTests.cs @@ -6,130 +6,129 @@ using Serilog.Sinks.SystemConsole.Themes; using Xunit; -namespace Serilog.Sinks.Console.Tests.Formatting +namespace Serilog.Sinks.Console.Tests.Formatting; + +public class ThemedJsonValueFormatterTests { - public class ThemedJsonValueFormatterTests + class TestThemedJsonValueFormatter : ThemedJsonValueFormatter { - class TestThemedJsonValueFormatter : ThemedJsonValueFormatter + public TestThemedJsonValueFormatter() + : base(ConsoleTheme.None, null) { - public TestThemedJsonValueFormatter() - : base(ConsoleTheme.None, null) - { - } - - public string Format(object literal) - { - var output = new StringWriter(); - Format(new SequenceValue(new[] { new ScalarValue(literal) }), output, null); - var o = output.ToString(); - return o.Substring(1, o.Length - 2); - } } - [Theory] - [InlineData(123, "123")] - [InlineData('c', "\"c\"")] - [InlineData("Hello, world!", "\"Hello, world!\"")] - [InlineData(true, "true")] - [InlineData("\\\"\t\r\n\f", "\"\\\\\\\"\\t\\r\\n\\f\"")] - [InlineData("\u0001", "\"\\u0001\"")] - [InlineData("a\nb", "\"a\\nb\"")] - [InlineData(null, "null")] - public void JsonLiteralTypesAreFormatted(object value, string expectedJson) + public string Format(object literal) { - var formatter = new TestThemedJsonValueFormatter(); - Assert.Equal(expectedJson, formatter.Format(value)); + var output = new StringWriter(); + Format(new SequenceValue(new[] { new ScalarValue(literal) }), output, null); + var o = output.ToString(); + return o.Substring(1, o.Length - 2); } + } - [Fact] - public void DateTimesFormatAsIso8601() - { - JsonLiteralTypesAreFormatted(new DateTime(2016, 01, 01, 13, 13, 13, DateTimeKind.Utc), "\"2016-01-01T13:13:13.0000000Z\""); - } + [Theory] + [InlineData(123, "123")] + [InlineData('c', "\"c\"")] + [InlineData("Hello, world!", "\"Hello, world!\"")] + [InlineData(true, "true")] + [InlineData("\\\"\t\r\n\f", "\"\\\\\\\"\\t\\r\\n\\f\"")] + [InlineData("\u0001", "\"\\u0001\"")] + [InlineData("a\nb", "\"a\\nb\"")] + [InlineData(null, "null")] + public void JsonLiteralTypesAreFormatted(object value, string expectedJson) + { + var formatter = new TestThemedJsonValueFormatter(); + Assert.Equal(expectedJson, formatter.Format(value)); + } - [Fact] - public void DoubleFormatsAsNumber() - { - JsonLiteralTypesAreFormatted(123.45, "123.45"); - } + [Fact] + public void DateTimesFormatAsIso8601() + { + JsonLiteralTypesAreFormatted(new DateTime(2016, 01, 01, 13, 13, 13, DateTimeKind.Utc), "\"2016-01-01T13:13:13.0000000Z\""); + } - [Fact] - public void DoubleSpecialsFormatAsString() - { - JsonLiteralTypesAreFormatted(double.NaN, "\"NaN\""); - JsonLiteralTypesAreFormatted(double.PositiveInfinity, "\"Infinity\""); - JsonLiteralTypesAreFormatted(double.NegativeInfinity, "\"-Infinity\""); - } + [Fact] + public void DoubleFormatsAsNumber() + { + JsonLiteralTypesAreFormatted(123.45, "123.45"); + } - [Fact] - public void FloatFormatsAsNumber() - { - JsonLiteralTypesAreFormatted(123.45f, "123.45"); - } + [Fact] + public void DoubleSpecialsFormatAsString() + { + JsonLiteralTypesAreFormatted(double.NaN, "\"NaN\""); + JsonLiteralTypesAreFormatted(double.PositiveInfinity, "\"Infinity\""); + JsonLiteralTypesAreFormatted(double.NegativeInfinity, "\"-Infinity\""); + } - [Fact] - public void FloatSpecialsFormatAsString() - { - JsonLiteralTypesAreFormatted(float.NaN, "\"NaN\""); - JsonLiteralTypesAreFormatted(float.PositiveInfinity, "\"Infinity\""); - JsonLiteralTypesAreFormatted(float.NegativeInfinity, "\"-Infinity\""); - } + [Fact] + public void FloatFormatsAsNumber() + { + JsonLiteralTypesAreFormatted(123.45f, "123.45"); + } - [Fact] - public void DecimalFormatsAsNumber() - { - JsonLiteralTypesAreFormatted(123.45m, "123.45"); - } + [Fact] + public void FloatSpecialsFormatAsString() + { + JsonLiteralTypesAreFormatted(float.NaN, "\"NaN\""); + JsonLiteralTypesAreFormatted(float.PositiveInfinity, "\"Infinity\""); + JsonLiteralTypesAreFormatted(float.NegativeInfinity, "\"-Infinity\""); + } - static string Format(LogEventPropertyValue value) - { - var formatter = new TestThemedJsonValueFormatter(); - var output = new StringWriter(); - formatter.Format(value, output, null); - return output.ToString(); - } + [Fact] + public void DecimalFormatsAsNumber() + { + JsonLiteralTypesAreFormatted(123.45m, "123.45"); + } - [Fact] - public void ScalarPropertiesFormatAsLiteralValues() - { - var f = Format(new ScalarValue(123)); - Assert.Equal("123", f); - } + static string Format(LogEventPropertyValue value) + { + var formatter = new TestThemedJsonValueFormatter(); + var output = new StringWriter(); + formatter.Format(value, output, null); + return output.ToString(); + } - [Fact] - public void SequencePropertiesFormatAsArrayValue() - { - var f = Format(new SequenceValue(new[] { new ScalarValue(123), new ScalarValue(456) })); - Assert.Equal("[123, 456]", f); - } + [Fact] + public void ScalarPropertiesFormatAsLiteralValues() + { + var f = Format(new ScalarValue(123)); + Assert.Equal("123", f); + } - [Fact] - public void StructuresFormatAsAnObject() - { - var structure = new StructureValue(new[] { new LogEventProperty("A", new ScalarValue(123)) }, "T"); - var f = Format(structure); - Assert.Equal("{\"A\": 123, \"$type\": \"T\"}", f); - } + [Fact] + public void SequencePropertiesFormatAsArrayValue() + { + var f = Format(new SequenceValue(new[] { new ScalarValue(123), new ScalarValue(456) })); + Assert.Equal("[123, 456]", f); + } + + [Fact] + public void StructuresFormatAsAnObject() + { + var structure = new StructureValue(new[] { new LogEventProperty("A", new ScalarValue(123)) }, "T"); + var f = Format(structure); + Assert.Equal("{\"A\": 123, \"$type\": \"T\"}", f); + } - [Fact] - public void DictionaryWithScalarKeyFormatsAsAnObject() + [Fact] + public void DictionaryWithScalarKeyFormatsAsAnObject() + { + var dict = new DictionaryValue(new Dictionary { - var dict = new DictionaryValue(new Dictionary - { - { new ScalarValue(12), new ScalarValue(345) }, - }); + { new ScalarValue(12), new ScalarValue(345) }, + }); - var f = Format(dict); - Assert.Equal("{\"12\": 345}", f); - } + var f = Format(dict); + Assert.Equal("{\"12\": 345}", f); + } - [Fact] - public void SequencesOfSequencesAreFormatted() - { - var s = new SequenceValue(new[] { new SequenceValue(new[] { new ScalarValue("Hello") }) }); + [Fact] + public void SequencesOfSequencesAreFormatted() + { + var s = new SequenceValue(new[] { new SequenceValue(new[] { new ScalarValue("Hello") }) }); - var f = Format(s); - Assert.Equal("[[\"Hello\"]]", f); - } + var f = Format(s); + Assert.Equal("[[\"Hello\"]]", f); } -} +} \ No newline at end of file diff --git a/test/Serilog.Sinks.Console.Tests/Output/OutputTemplateRendererTests.cs b/test/Serilog.Sinks.Console.Tests/Output/OutputTemplateRendererTests.cs index 59bbedc..8e5f731 100644 --- a/test/Serilog.Sinks.Console.Tests/Output/OutputTemplateRendererTests.cs +++ b/test/Serilog.Sinks.Console.Tests/Output/OutputTemplateRendererTests.cs @@ -10,395 +10,394 @@ using Serilog.Sinks.SystemConsole.Themes; using Xunit; -namespace Serilog.Sinks.Console.Tests.Output +namespace Serilog.Sinks.Console.Tests.Output; + +public class OutputTemplateRendererTests { - public class OutputTemplateRendererTests + [Fact] + public void UsesFormatProvider() { - [Fact] - public void UsesFormatProvider() - { - var french = new CultureInfo("fr-FR"); - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message}", french); - var evt = DelegatingSink.GetLogEvent(l => l.Information("{0}", 12.345)); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("12,345", sw.ToString()); - } + var french = new CultureInfo("fr-FR"); + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message}", french); + var evt = DelegatingSink.GetLogEvent(l => l.Information("{0}", 12.345)); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("12,345", sw.ToString()); + } - [Fact] - public void MessageTemplatesContainingFormatStringPropertiesRenderCorrectly() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("{Message}", "Hello, world!")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("\"Hello, world!\"", sw.ToString()); - } + [Fact] + public void MessageTemplatesContainingFormatStringPropertiesRenderCorrectly() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("{Message}", "Hello, world!")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("\"Hello, world!\"", sw.ToString()); + } - [Fact] - public void UppercaseFormatSpecifierIsSupportedForStrings() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Name:u}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("{Name}", "Nick")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("NICK", sw.ToString()); - } + [Fact] + public void UppercaseFormatSpecifierIsSupportedForStrings() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Name:u}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("{Name}", "Nick")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("NICK", sw.ToString()); + } - [Fact] - public void LowercaseFormatSpecifierIsSupportedForStrings() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Name:w}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("{Name}", "Nick")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("nick", sw.ToString()); - } + [Fact] + public void LowercaseFormatSpecifierIsSupportedForStrings() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Name:w}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("{Name}", "Nick")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("nick", sw.ToString()); + } - [Theory] - [InlineData(LogEventLevel.Verbose, 1, "V")] - [InlineData(LogEventLevel.Verbose, 2, "Vb")] - [InlineData(LogEventLevel.Verbose, 3, "Vrb")] - [InlineData(LogEventLevel.Verbose, 4, "Verb")] - [InlineData(LogEventLevel.Verbose, 5, "Verbo")] - [InlineData(LogEventLevel.Verbose, 6, "Verbos")] - [InlineData(LogEventLevel.Verbose, 7, "Verbose")] - [InlineData(LogEventLevel.Verbose, 8, "Verbose")] - [InlineData(LogEventLevel.Debug, 1, "D")] - [InlineData(LogEventLevel.Debug, 2, "De")] - [InlineData(LogEventLevel.Debug, 3, "Dbg")] - [InlineData(LogEventLevel.Debug, 4, "Dbug")] - [InlineData(LogEventLevel.Debug, 5, "Debug")] - [InlineData(LogEventLevel.Debug, 6, "Debug")] - [InlineData(LogEventLevel.Information, 1, "I")] - [InlineData(LogEventLevel.Information, 2, "In")] - [InlineData(LogEventLevel.Information, 3, "Inf")] - [InlineData(LogEventLevel.Information, 4, "Info")] - [InlineData(LogEventLevel.Information, 5, "Infor")] - [InlineData(LogEventLevel.Information, 6, "Inform")] - [InlineData(LogEventLevel.Information, 7, "Informa")] - [InlineData(LogEventLevel.Information, 8, "Informat")] - [InlineData(LogEventLevel.Information, 9, "Informati")] - [InlineData(LogEventLevel.Information, 10, "Informatio")] - [InlineData(LogEventLevel.Information, 11, "Information")] - [InlineData(LogEventLevel.Information, 12, "Information")] - [InlineData(LogEventLevel.Error, 1, "E")] - [InlineData(LogEventLevel.Error, 2, "Er")] - [InlineData(LogEventLevel.Error, 3, "Err")] - [InlineData(LogEventLevel.Error, 4, "Eror")] - [InlineData(LogEventLevel.Error, 5, "Error")] - [InlineData(LogEventLevel.Error, 6, "Error")] - [InlineData(LogEventLevel.Fatal, 1, "F")] - [InlineData(LogEventLevel.Fatal, 2, "Fa")] - [InlineData(LogEventLevel.Fatal, 3, "Ftl")] - [InlineData(LogEventLevel.Fatal, 4, "Fatl")] - [InlineData(LogEventLevel.Fatal, 5, "Fatal")] - [InlineData(LogEventLevel.Fatal, 6, "Fatal")] - [InlineData(LogEventLevel.Warning, 1, "W")] - [InlineData(LogEventLevel.Warning, 2, "Wn")] - [InlineData(LogEventLevel.Warning, 3, "Wrn")] - [InlineData(LogEventLevel.Warning, 4, "Warn")] - [InlineData(LogEventLevel.Warning, 5, "Warni")] - [InlineData(LogEventLevel.Warning, 6, "Warnin")] - [InlineData(LogEventLevel.Warning, 7, "Warning")] - [InlineData(LogEventLevel.Warning, 8, "Warning")] - public void FixedLengthLevelIsSupported( - LogEventLevel level, - int width, - string expected) - { - var formatter1 = new OutputTemplateRenderer(ConsoleTheme.None, $"{{Level:t{width}}}", CultureInfo.InvariantCulture); - var evt1 = DelegatingSink.GetLogEvent(l => l.Write(level, "Hello")); - var sw1 = new StringWriter(); - formatter1.Format(evt1, sw1); - Assert.Equal(expected, sw1.ToString()); - - var formatter2 = new OutputTemplateRenderer(ConsoleTheme.None, $"{{Level:u{width}}}", CultureInfo.InvariantCulture); - var evt2 = DelegatingSink.GetLogEvent(l => l.Write(level, "Hello")); - var sw2 = new StringWriter(); - formatter2.Format(evt2, sw2); - Assert.Equal(expected.ToUpper(), sw2.ToString()); - - var formatter3 = new OutputTemplateRenderer(ConsoleTheme.None, $"{{Level:w{width}}}", CultureInfo.InvariantCulture); - var evt3 = DelegatingSink.GetLogEvent(l => l.Write(level, "Hello")); - var sw3 = new StringWriter(); - formatter3.Format(evt3, sw3); - Assert.Equal(expected.ToLower(), sw3.ToString()); - } + [Theory] + [InlineData(LogEventLevel.Verbose, 1, "V")] + [InlineData(LogEventLevel.Verbose, 2, "Vb")] + [InlineData(LogEventLevel.Verbose, 3, "Vrb")] + [InlineData(LogEventLevel.Verbose, 4, "Verb")] + [InlineData(LogEventLevel.Verbose, 5, "Verbo")] + [InlineData(LogEventLevel.Verbose, 6, "Verbos")] + [InlineData(LogEventLevel.Verbose, 7, "Verbose")] + [InlineData(LogEventLevel.Verbose, 8, "Verbose")] + [InlineData(LogEventLevel.Debug, 1, "D")] + [InlineData(LogEventLevel.Debug, 2, "De")] + [InlineData(LogEventLevel.Debug, 3, "Dbg")] + [InlineData(LogEventLevel.Debug, 4, "Dbug")] + [InlineData(LogEventLevel.Debug, 5, "Debug")] + [InlineData(LogEventLevel.Debug, 6, "Debug")] + [InlineData(LogEventLevel.Information, 1, "I")] + [InlineData(LogEventLevel.Information, 2, "In")] + [InlineData(LogEventLevel.Information, 3, "Inf")] + [InlineData(LogEventLevel.Information, 4, "Info")] + [InlineData(LogEventLevel.Information, 5, "Infor")] + [InlineData(LogEventLevel.Information, 6, "Inform")] + [InlineData(LogEventLevel.Information, 7, "Informa")] + [InlineData(LogEventLevel.Information, 8, "Informat")] + [InlineData(LogEventLevel.Information, 9, "Informati")] + [InlineData(LogEventLevel.Information, 10, "Informatio")] + [InlineData(LogEventLevel.Information, 11, "Information")] + [InlineData(LogEventLevel.Information, 12, "Information")] + [InlineData(LogEventLevel.Error, 1, "E")] + [InlineData(LogEventLevel.Error, 2, "Er")] + [InlineData(LogEventLevel.Error, 3, "Err")] + [InlineData(LogEventLevel.Error, 4, "Eror")] + [InlineData(LogEventLevel.Error, 5, "Error")] + [InlineData(LogEventLevel.Error, 6, "Error")] + [InlineData(LogEventLevel.Fatal, 1, "F")] + [InlineData(LogEventLevel.Fatal, 2, "Fa")] + [InlineData(LogEventLevel.Fatal, 3, "Ftl")] + [InlineData(LogEventLevel.Fatal, 4, "Fatl")] + [InlineData(LogEventLevel.Fatal, 5, "Fatal")] + [InlineData(LogEventLevel.Fatal, 6, "Fatal")] + [InlineData(LogEventLevel.Warning, 1, "W")] + [InlineData(LogEventLevel.Warning, 2, "Wn")] + [InlineData(LogEventLevel.Warning, 3, "Wrn")] + [InlineData(LogEventLevel.Warning, 4, "Warn")] + [InlineData(LogEventLevel.Warning, 5, "Warni")] + [InlineData(LogEventLevel.Warning, 6, "Warnin")] + [InlineData(LogEventLevel.Warning, 7, "Warning")] + [InlineData(LogEventLevel.Warning, 8, "Warning")] + public void FixedLengthLevelIsSupported( + LogEventLevel level, + int width, + string expected) + { + var formatter1 = new OutputTemplateRenderer(ConsoleTheme.None, $"{{Level:t{width}}}", CultureInfo.InvariantCulture); + var evt1 = DelegatingSink.GetLogEvent(l => l.Write(level, "Hello")); + var sw1 = new StringWriter(); + formatter1.Format(evt1, sw1); + Assert.Equal(expected, sw1.ToString()); + + var formatter2 = new OutputTemplateRenderer(ConsoleTheme.None, $"{{Level:u{width}}}", CultureInfo.InvariantCulture); + var evt2 = DelegatingSink.GetLogEvent(l => l.Write(level, "Hello")); + var sw2 = new StringWriter(); + formatter2.Format(evt2, sw2); + Assert.Equal(expected.ToUpper(), sw2.ToString()); + + var formatter3 = new OutputTemplateRenderer(ConsoleTheme.None, $"{{Level:w{width}}}", CultureInfo.InvariantCulture); + var evt3 = DelegatingSink.GetLogEvent(l => l.Write(level, "Hello")); + var sw3 = new StringWriter(); + formatter3.Format(evt3, sw3); + Assert.Equal(expected.ToLower(), sw3.ToString()); + } - [Fact] - public void FixedLengthLevelSupportsUpperCasing() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level:u3}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("INF", sw.ToString()); - } + [Fact] + public void FixedLengthLevelSupportsUpperCasing() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level:u3}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("INF", sw.ToString()); + } - [Fact] - public void FixedLengthLevelSupportsLowerCasing() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level:w3}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("inf", sw.ToString()); - } + [Fact] + public void FixedLengthLevelSupportsLowerCasing() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level:w3}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("inf", sw.ToString()); + } - [Fact] - public void FixedLengthLevelSupportsCasingForWideNames() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level:w6}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("inform", sw.ToString()); - } + [Fact] + public void FixedLengthLevelSupportsCasingForWideNames() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level:w6}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("inform", sw.ToString()); + } - [Fact] - public void DefaultLevelLengthIsFullText() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("Information", sw.ToString()); - } + [Fact] + public void DefaultLevelLengthIsFullText() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("Information", sw.ToString()); + } - [Fact] - public void AlignmentAndWidthCanBeCombined() + [Fact] + public void AlignmentAndWidthCanBeCombined() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level,5:w3}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal(" inf", sw.ToString()); + } + + enum Size + { + Large + } + + class SizeFormatter : IFormatProvider, ICustomFormatter + { + readonly IFormatProvider _innerFormatProvider; + + public SizeFormatter(IFormatProvider innerFormatProvider) { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Level,5:w3}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal(" inf", sw.ToString()); + _innerFormatProvider = innerFormatProvider; } - enum Size + public object GetFormat(Type? formatType) { - Large + return formatType == typeof(ICustomFormatter) ? this : _innerFormatProvider.GetFormat(formatType) ?? this; } - class SizeFormatter : IFormatProvider, ICustomFormatter + public string Format(string? format, object? arg, IFormatProvider? formatProvider) { - readonly IFormatProvider _innerFormatProvider; + if (arg is Size size) + return size == Size.Large ? "Huge" : size.ToString(); - public SizeFormatter(IFormatProvider innerFormatProvider) - { - _innerFormatProvider = innerFormatProvider; - } + if (arg is IFormattable formattable) + return formattable.ToString(format, _innerFormatProvider); - public object GetFormat(Type? formatType) - { - return formatType == typeof(ICustomFormatter) ? this : _innerFormatProvider.GetFormat(formatType) ?? this; - } + return arg?.ToString() ?? ""; + } + } - public string Format(string? format, object? arg, IFormatProvider? formatProvider) - { - if (arg is Size size) - return size == Size.Large ? "Huge" : size.ToString(); + [Fact] + public void AppliesCustomFormatterToEnums() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message}", new SizeFormatter(CultureInfo.InvariantCulture)); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Size {Size}", Size.Large)); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("Size Huge", sw.ToString()); + } - if (arg is IFormattable formattable) - return formattable.ToString(format, _innerFormatProvider); + [Fact] + public void NonMessagePropertiesAreRendered() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Properties}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.ForContext("Foo", 42).Information("Hello from {Bar}!", "bar")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("{Foo=42}", sw.ToString()); + } - return arg?.ToString() ?? ""; - } - } + [Fact] + public void NonMessagePositionalPropertiesAreRendered() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Properties}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.ForContext("Foo", 42).Information("Hello from {0}!", "bar")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("{Foo=42}", sw.ToString()); + } - [Fact] - public void AppliesCustomFormatterToEnums() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message}", new SizeFormatter(CultureInfo.InvariantCulture)); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Size {Size}", Size.Large)); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("Size Huge", sw.ToString()); - } + [Fact] + public void DoNotDuplicatePropertiesAlreadyRenderedInOutputTemplate() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Foo} {Properties}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.ForContext("Foo", 42).ForContext("Bar", 42).Information("Hello from bar!")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("42 {Bar=42}", sw.ToString()); + } - [Fact] - public void NonMessagePropertiesAreRendered() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Properties}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.ForContext("Foo", 42).Information("Hello from {Bar}!", "bar")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("{Foo=42}", sw.ToString()); - } + [Theory] + [InlineData("", "Hello, \"World\"!")] + [InlineData(":j", "Hello, \"World\"!")] + [InlineData(":l", "Hello, World!")] + [InlineData(":lj", "Hello, World!")] + [InlineData(":jl", "Hello, World!")] + public void AppliesLiteralFormattingToMessageStringsWhenSpecified(string format, string expected) + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message" + format + "}", null); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello, {Name}!", "World")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal(expected, sw.ToString()); + } - [Fact] - public void NonMessagePositionalPropertiesAreRendered() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Properties}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.ForContext("Foo", 42).Information("Hello from {0}!", "bar")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("{Foo=42}", sw.ToString()); - } + [Theory] + [InlineData("", "{Name=\"World\"}")] + [InlineData(":j", "{\"Name\": \"World\"}")] + [InlineData(":lj", "{\"Name\": \"World\"}")] + [InlineData(":jl", "{\"Name\": \"World\"}")] + public void AppliesJsonFormattingToMessageStructuresWhenSpecified(string format, string expected) + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message" + format + "}", null); + var evt = DelegatingSink.GetLogEvent(l => l.Information("{@Obj}", new { Name = "World" })); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal(expected, sw.ToString()); + } - [Fact] - public void DoNotDuplicatePropertiesAlreadyRenderedInOutputTemplate() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Foo} {Properties}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.ForContext("Foo", 42).ForContext("Bar", 42).Information("Hello from bar!")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("42 {Bar=42}", sw.ToString()); - } + [Theory] + [InlineData("", "{Name=\"World\"}")] + [InlineData(":j", "{\"Name\": \"World\"}")] + [InlineData(":lj", "{\"Name\": \"World\"}")] + [InlineData(":jl", "{\"Name\": \"World\"}")] + public void AppliesJsonFormattingToPropertiesTokenWhenSpecified(string format, string expected) + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Properties" + format + "}", null); + var evt = DelegatingSink.GetLogEvent(l => l.ForContext("Name", "World").Information("Hello")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal(expected, sw.ToString()); + } - [Theory] - [InlineData("", "Hello, \"World\"!")] - [InlineData(":j", "Hello, \"World\"!")] - [InlineData(":l", "Hello, World!")] - [InlineData(":lj", "Hello, World!")] - [InlineData(":jl", "Hello, World!")] - public void AppliesLiteralFormattingToMessageStringsWhenSpecified(string format, string expected) - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message" + format + "}", null); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello, {Name}!", "World")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal(expected, sw.ToString()); - } + [Fact] + public void AnEmptyPropertiesTokenIsAnEmptyStructureValue() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Properties}", null); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + + // /!\ different behavior from Serilog Core : https://github.com/serilog/serilog/blob/5c3a7821aa0f654e551dc21e8e19089f6767666b/test/Serilog.Tests/Formatting/Display/MessageTemplateTextFormatterTests.cs#L268-L278 + // + // var expected = new StructureValue(Enumerable.Empty()).ToString(); + // // expected == "{ }" + // Assert.Equal(expected, sw.ToString()); + // + Assert.Equal("{}", sw.ToString()); + } - [Theory] - [InlineData("", "{Name=\"World\"}")] - [InlineData(":j", "{\"Name\": \"World\"}")] - [InlineData(":lj", "{\"Name\": \"World\"}")] - [InlineData(":jl", "{\"Name\": \"World\"}")] - public void AppliesJsonFormattingToMessageStructuresWhenSpecified(string format, string expected) - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message" + format + "}", null); - var evt = DelegatingSink.GetLogEvent(l => l.Information("{@Obj}", new { Name = "World" })); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal(expected, sw.ToString()); - } + [Theory] + [InlineData("", true)] + [InlineData(":lj", true)] + [InlineData(":jl", true)] + [InlineData(":j", false)] + [InlineData(":l", true)] + public void FormatProviderWithScalarProperties(string format, bool shouldUseCustomFormatter) + { + var frenchFormatProvider = new CultureInfo("fr-FR"); + var defaultFormatProvider = CultureInfo.InvariantCulture; - [Theory] - [InlineData("", "{Name=\"World\"}")] - [InlineData(":j", "{\"Name\": \"World\"}")] - [InlineData(":lj", "{\"Name\": \"World\"}")] - [InlineData(":jl", "{\"Name\": \"World\"}")] - public void AppliesJsonFormattingToPropertiesTokenWhenSpecified(string format, string expected) - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Properties" + format + "}", null); - var evt = DelegatingSink.GetLogEvent(l => l.ForContext("Name", "World").Information("Hello")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal(expected, sw.ToString()); - } + var date = new DateTime(2018, 01, 01); + var number = 12.345; - [Fact] - public void AnEmptyPropertiesTokenIsAnEmptyStructureValue() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Properties}", null); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - - // /!\ different behavior from Serilog Core : https://github.com/serilog/serilog/blob/5c3a7821aa0f654e551dc21e8e19089f6767666b/test/Serilog.Tests/Formatting/Display/MessageTemplateTextFormatterTests.cs#L268-L278 - // - // var expected = new StructureValue(Enumerable.Empty()).ToString(); - // // expected == "{ }" - // Assert.Equal(expected, sw.ToString()); - // - Assert.Equal("{}", sw.ToString()); - } + var expectedFormattedDate = shouldUseCustomFormatter + ? date.ToString(frenchFormatProvider) + : date.ToString("O", defaultFormatProvider); + var expectedFormattedNumber = shouldUseCustomFormatter + ? number.ToString(frenchFormatProvider) + : number.ToString(defaultFormatProvider); - [Theory] - [InlineData("", true)] - [InlineData(":lj", true)] - [InlineData(":jl", true)] - [InlineData(":j", false)] - [InlineData(":l", true)] - public void FormatProviderWithScalarProperties(string format, bool shouldUseCustomFormatter) + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message" + format + "}", frenchFormatProvider); + var evt = DelegatingSink.GetLogEvent(l => { - var frenchFormatProvider = new CultureInfo("fr-FR"); - var defaultFormatProvider = CultureInfo.InvariantCulture; + l.Information("{MyDate}{MyNumber}", date, number); + }); + var sw = new StringWriter(); + formatter.Format(evt, sw); - var date = new DateTime(2018, 01, 01); - var number = 12.345; + Assert.Contains(expectedFormattedDate, sw.ToString()); + Assert.Contains(expectedFormattedNumber, sw.ToString()); + } - var expectedFormattedDate = shouldUseCustomFormatter - ? date.ToString(frenchFormatProvider) - : date.ToString("O", defaultFormatProvider); - var expectedFormattedNumber = shouldUseCustomFormatter - ? number.ToString(frenchFormatProvider) - : number.ToString(defaultFormatProvider); + [Theory] + [InlineData("", true)] + [InlineData(":lj", false)] + [InlineData(":jl", false)] + [InlineData(":j", false)] + [InlineData(":l", true)] + public void FormatProviderWithDestructuredProperties(string format, bool shouldUseCustomFormatter) + { + var frenchFormatProvider = new CultureInfo("fr-FR"); + var defaultFormatProvider = CultureInfo.InvariantCulture; - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message" + format + "}", frenchFormatProvider); - var evt = DelegatingSink.GetLogEvent(l => - { - l.Information("{MyDate}{MyNumber}", date, number); - }); - var sw = new StringWriter(); - formatter.Format(evt, sw); + var date = new DateTime(2018, 01, 01); + var number = 12.345; - Assert.Contains(expectedFormattedDate, sw.ToString()); - Assert.Contains(expectedFormattedNumber, sw.ToString()); - } + var expectedFormattedDate = shouldUseCustomFormatter + ? date.ToString(frenchFormatProvider) + : date.ToString("O", defaultFormatProvider); + var expectedFormattedNumber = shouldUseCustomFormatter + ? number.ToString(frenchFormatProvider) + : number.ToString(defaultFormatProvider); - [Theory] - [InlineData("", true)] - [InlineData(":lj", false)] - [InlineData(":jl", false)] - [InlineData(":j", false)] - [InlineData(":l", true)] - public void FormatProviderWithDestructuredProperties(string format, bool shouldUseCustomFormatter) + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message" + format + "}", frenchFormatProvider); + var evt = DelegatingSink.GetLogEvent(l => { - var frenchFormatProvider = new CultureInfo("fr-FR"); - var defaultFormatProvider = CultureInfo.InvariantCulture; - - var date = new DateTime(2018, 01, 01); - var number = 12.345; - - var expectedFormattedDate = shouldUseCustomFormatter - ? date.ToString(frenchFormatProvider) - : date.ToString("O", defaultFormatProvider); - var expectedFormattedNumber = shouldUseCustomFormatter - ? number.ToString(frenchFormatProvider) - : number.ToString(defaultFormatProvider); - - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{Message" + format + "}", frenchFormatProvider); - var evt = DelegatingSink.GetLogEvent(l => + l.Information("{@Item}", new { - l.Information("{@Item}", new - { - MyDate = date, - MyNumber = number, - }); + MyDate = date, + MyNumber = number, }); - var sw = new StringWriter(); - formatter.Format(evt, sw); + }); + var sw = new StringWriter(); + formatter.Format(evt, sw); - Assert.Contains(expectedFormattedDate, sw.ToString()); - Assert.Contains(expectedFormattedNumber, sw.ToString()); - } + Assert.Contains(expectedFormattedDate, sw.ToString()); + Assert.Contains(expectedFormattedNumber, sw.ToString()); + } - [Fact] - public void TraceAndSpanAreEmptyWhenAbsent() - { - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{TraceId}/{SpanId}", CultureInfo.InvariantCulture); - var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello, world")); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal("/", sw.ToString()); - } + [Fact] + public void TraceAndSpanAreEmptyWhenAbsent() + { + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{TraceId}/{SpanId}", CultureInfo.InvariantCulture); + var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello, world")); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal("/", sw.ToString()); + } - [Fact] - public void TraceAndSpanAreIncludedWhenPresent() - { - var traceId = ActivityTraceId.CreateRandom(); - var spanId = ActivitySpanId.CreateRandom(); - var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{TraceId}/{SpanId}", CultureInfo.InvariantCulture); - var evt = new LogEvent(DateTimeOffset.Now, LogEventLevel.Debug, null, - new MessageTemplate(Enumerable.Empty()), Enumerable.Empty(), - traceId, spanId); - var sw = new StringWriter(); - formatter.Format(evt, sw); - Assert.Equal($"{traceId}/{spanId}", sw.ToString()); - } + [Fact] + public void TraceAndSpanAreIncludedWhenPresent() + { + var traceId = ActivityTraceId.CreateRandom(); + var spanId = ActivitySpanId.CreateRandom(); + var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{TraceId}/{SpanId}", CultureInfo.InvariantCulture); + var evt = new LogEvent(DateTimeOffset.Now, LogEventLevel.Debug, null, + new MessageTemplate(Enumerable.Empty()), Enumerable.Empty(), + traceId, spanId); + var sw = new StringWriter(); + formatter.Format(evt, sw); + Assert.Equal($"{traceId}/{spanId}", sw.ToString()); } -} +} \ No newline at end of file diff --git a/test/Serilog.Sinks.Console.Tests/Rendering/ThemedMessageTemplateRendererTests.cs b/test/Serilog.Sinks.Console.Tests/Rendering/ThemedMessageTemplateRendererTests.cs index 031f118..690ee5f 100644 --- a/test/Serilog.Sinks.Console.Tests/Rendering/ThemedMessageTemplateRendererTests.cs +++ b/test/Serilog.Sinks.Console.Tests/Rendering/ThemedMessageTemplateRendererTests.cs @@ -8,196 +8,195 @@ using System.Text; using Xunit; -namespace Serilog.Sinks.Console.Tests.Rendering +namespace Serilog.Sinks.Console.Tests.Rendering; + +public class ThemedMessageTemplateRendererTests { - public class ThemedMessageTemplateRendererTests - { - class Chair - { - // ReSharper disable UnusedMember.Local - public string Back => "straight"; - - public int[] Legs => new[] { 1, 2, 3, 4 }; - - // ReSharper restore UnusedMember.Local - public override string ToString() => "a chair"; - } - - class Receipt - { - // ReSharper disable UnusedMember.Local - public decimal Sum => 12.345m; - - public DateTime When => new DateTime(2013, 5, 20, 16, 39, 0); - - // ReSharper restore UnusedMember.Local - public override string ToString() => "a receipt"; - } - - [Fact] - public void AnObjectIsRenderedInSimpleNotation() - { - var m = Render("I sat at {@Chair}", new Chair()); - Assert.Equal("I sat at Chair {Back=\"straight\", Legs=[1, 2, 3, 4]}", m); - } - - [Fact] - public void AnObjectIsRenderedInSimpleNotationUsingFormatProvider() - { - var m = Render(new CultureInfo("fr-FR"), "I received {@Receipt}", new Receipt()); - Assert.Equal("I received Receipt {Sum=12,345, When=20/05/2013 16:39:00}", m); - } - - [Fact] - public void AnAnonymousObjectIsRenderedInSimpleNotationWithoutType() - { - var m = Render("I sat at {@Chair}", new { Back = "straight", Legs = new[] { 1, 2, 3, 4 } }); - Assert.Equal("I sat at {Back=\"straight\", Legs=[1, 2, 3, 4]}", m); - } - - [Fact] - public void AnAnonymousObjectIsRenderedInSimpleNotationWithoutTypeUsingFormatProvider() - { - var m = Render(new CultureInfo("fr-FR"), "I received {@Receipt}", new { Sum = 12.345, When = new DateTime(2013, 5, 20, 16, 39, 0) }); - Assert.Equal("I received {Sum=12,345, When=20/05/2013 16:39:00}", m); - } - - [Fact] - public void AnObjectWithDefaultDestructuringIsRenderedAsAStringLiteral() - { - var m = Render("I sat at {Chair}", new Chair()); - Assert.Equal("I sat at \"a chair\"", m); - } - - [Fact] - public void AnObjectWithStringifyDestructuringIsRenderedAsAString() - { - var m = Render("I sat at {$Chair}", new Chair()); - Assert.Equal("I sat at \"a chair\"", m); - } - - [Fact] - public void MultiplePropertiesAreRenderedInOrder() - { - var m = Render("Just biting {Fruit} number {Count}", "Apple", 12); - Assert.Equal("Just biting \"Apple\" number 12", m); - } - - [Fact] - public void MultiplePropertiesUseFormatProvider() - { - var m = Render(new CultureInfo("fr-FR"), "Income was {Income} at {Date:d}", 1234.567, new DateTime(2013, 5, 20)); - Assert.Equal("Income was 1234,567 at 20/05/2013", m); - } - - [Fact] - public void FormatStringsArePropagated() - { - var m = Render("Welcome, customer {CustomerId:0000}", 12); - Assert.Equal("Welcome, customer 0012", m); - } - - [Theory] - [InlineData("Welcome, customer #{CustomerId,-10}, pleasure to see you", "Welcome, customer #1234 , pleasure to see you")] - [InlineData("Welcome, customer #{CustomerId,-10:000000}, pleasure to see you", "Welcome, customer #001234 , pleasure to see you")] - [InlineData("Welcome, customer #{CustomerId,10}, pleasure to see you", "Welcome, customer # 1234, pleasure to see you")] - [InlineData("Welcome, customer #{CustomerId,10:000000}, pleasure to see you", "Welcome, customer # 001234, pleasure to see you")] - [InlineData("Welcome, customer #{CustomerId,10:0,0}, pleasure to see you", "Welcome, customer # 1,234, pleasure to see you")] - [InlineData("Welcome, customer #{CustomerId:0,0}, pleasure to see you", "Welcome, customer #1,234, pleasure to see you")] - public void AlignmentStringsArePropagated(string value, string expected) - { - Assert.Equal(expected, Render(value, 1234)); - } - - [Fact] - public void FormatProviderIsUsed() - { - var m = Render(new CultureInfo("fr-FR"), "Please pay {Sum}", 12.345); - Assert.Equal("Please pay 12,345", m); - } - - static string Render(string messageTemplate, params object[] properties) - { - return Render(null, messageTemplate, properties); - } - - static string Render(IFormatProvider? formatProvider, string messageTemplate, params object[] properties) - { - var binder = new LoggerConfiguration().CreateLogger(); - if (binder.BindMessageTemplate(messageTemplate, properties, out var mt, out var props) == false) - throw new InvalidOperationException(); - - var output = new StringBuilder(); - var writer = new StringWriter(output); - var renderer = new ThemedMessageTemplateRenderer(ConsoleTheme.None, - new ThemedDisplayValueFormatter(ConsoleTheme.None, formatProvider), false); - renderer.Render(mt, props.ToDictionary(p => p.Name, p => p.Value), writer); - writer.Flush(); - return output.ToString(); - } - - [Fact] - public void ATemplateWithOnlyPositionalPropertiesIsAnalyzedAndRenderedPositionally() - { - var m = Render("{1}, {0}", "world", "Hello"); - Assert.Equal("\"Hello\", \"world\"", m); - } - - [Fact] - public void ATemplateWithOnlyPositionalPropertiesUsesFormatProvider() - { - var m = Render(new CultureInfo("fr-FR"), "{1}, {0}", 12.345, "Hello"); - Assert.Equal("\"Hello\", 12,345", m); - } - - // Debatable what the behavior should be, here. - [Fact] - public void ATemplateWithNamesAndPositionalsUsesNamesForAllValues() - { - var m = Render("{1}, {Place}", "world", "Hello"); - Assert.Equal("\"world\", \"Hello\"", m); - } - - [Fact] - public void MissingPositionalParametersRenderAsTextLikeStandardFormats() - { - var m = Render("{1}, {0}", "world"); - Assert.Equal("{1}, \"world\"", m); - } - - [Fact] - public void AnonymousTypeShouldBeRendered() - { - var anonymous = new { Test = 3M }; - var m = Render("Anonymous type {value}", anonymous); - Assert.Equal("Anonymous type \"{ Test = 3 }\"", m); - } - - [Fact] - public void EnumerableOfAnonymousTypeShouldBeRendered() - { - var anonymous = new { Foo = 4M, Bar = "Baz" }; - var enumerable = Enumerable.Repeat("MyKey", 1).Select(v => anonymous); - var m = Render("Enumerable with anonymous type {enumerable}", enumerable); - Assert.Equal("Enumerable with anonymous type [\"{ Foo = 4, Bar = Baz }\"]", m); - } - - [Fact] - public void DictionaryOfAnonymousTypeAsValueShouldBeRendered() - { - var anonymous = new { Test = 5M }; - var dictionary = Enumerable.Repeat("MyKey", 1).ToDictionary(v => v, v => anonymous); - var m = Render("Dictionary with anonymous type value {dictionary}", dictionary); - Assert.Equal("Dictionary with anonymous type value {[\"MyKey\"]=\"{ Test = 5 }\"}", m); - } - - [Fact] - public void DictionaryOfAnonymousTypeAsKeyShouldBeRendered() - { - var anonymous = new { Bar = 6M, Baz = 4M }; - var dictionary = Enumerable.Repeat("MyValue", 1).ToDictionary(v => anonymous, v => v); - var m = Render("Dictionary with anonymous type key {dictionary}", dictionary); - Assert.Equal("Dictionary with anonymous type key [\"[{ Bar = 6, Baz = 4 }, MyValue]\"]", m); - } + class Chair + { + // ReSharper disable UnusedMember.Local + public string Back => "straight"; + + public int[] Legs => new[] { 1, 2, 3, 4 }; + + // ReSharper restore UnusedMember.Local + public override string ToString() => "a chair"; + } + + class Receipt + { + // ReSharper disable UnusedMember.Local + public decimal Sum => 12.345m; + + public DateTime When => new DateTime(2013, 5, 20, 16, 39, 0); + + // ReSharper restore UnusedMember.Local + public override string ToString() => "a receipt"; + } + + [Fact] + public void AnObjectIsRenderedInSimpleNotation() + { + var m = Render("I sat at {@Chair}", new Chair()); + Assert.Equal("I sat at Chair {Back=\"straight\", Legs=[1, 2, 3, 4]}", m); + } + + [Fact] + public void AnObjectIsRenderedInSimpleNotationUsingFormatProvider() + { + var m = Render(new CultureInfo("fr-FR"), "I received {@Receipt}", new Receipt()); + Assert.Equal("I received Receipt {Sum=12,345, When=20/05/2013 16:39:00}", m); + } + + [Fact] + public void AnAnonymousObjectIsRenderedInSimpleNotationWithoutType() + { + var m = Render("I sat at {@Chair}", new { Back = "straight", Legs = new[] { 1, 2, 3, 4 } }); + Assert.Equal("I sat at {Back=\"straight\", Legs=[1, 2, 3, 4]}", m); + } + + [Fact] + public void AnAnonymousObjectIsRenderedInSimpleNotationWithoutTypeUsingFormatProvider() + { + var m = Render(new CultureInfo("fr-FR"), "I received {@Receipt}", new { Sum = 12.345, When = new DateTime(2013, 5, 20, 16, 39, 0) }); + Assert.Equal("I received {Sum=12,345, When=20/05/2013 16:39:00}", m); + } + + [Fact] + public void AnObjectWithDefaultDestructuringIsRenderedAsAStringLiteral() + { + var m = Render("I sat at {Chair}", new Chair()); + Assert.Equal("I sat at \"a chair\"", m); + } + + [Fact] + public void AnObjectWithStringifyDestructuringIsRenderedAsAString() + { + var m = Render("I sat at {$Chair}", new Chair()); + Assert.Equal("I sat at \"a chair\"", m); + } + + [Fact] + public void MultiplePropertiesAreRenderedInOrder() + { + var m = Render("Just biting {Fruit} number {Count}", "Apple", 12); + Assert.Equal("Just biting \"Apple\" number 12", m); + } + + [Fact] + public void MultiplePropertiesUseFormatProvider() + { + var m = Render(new CultureInfo("fr-FR"), "Income was {Income} at {Date:d}", 1234.567, new DateTime(2013, 5, 20)); + Assert.Equal("Income was 1234,567 at 20/05/2013", m); + } + + [Fact] + public void FormatStringsArePropagated() + { + var m = Render("Welcome, customer {CustomerId:0000}", 12); + Assert.Equal("Welcome, customer 0012", m); + } + + [Theory] + [InlineData("Welcome, customer #{CustomerId,-10}, pleasure to see you", "Welcome, customer #1234 , pleasure to see you")] + [InlineData("Welcome, customer #{CustomerId,-10:000000}, pleasure to see you", "Welcome, customer #001234 , pleasure to see you")] + [InlineData("Welcome, customer #{CustomerId,10}, pleasure to see you", "Welcome, customer # 1234, pleasure to see you")] + [InlineData("Welcome, customer #{CustomerId,10:000000}, pleasure to see you", "Welcome, customer # 001234, pleasure to see you")] + [InlineData("Welcome, customer #{CustomerId,10:0,0}, pleasure to see you", "Welcome, customer # 1,234, pleasure to see you")] + [InlineData("Welcome, customer #{CustomerId:0,0}, pleasure to see you", "Welcome, customer #1,234, pleasure to see you")] + public void AlignmentStringsArePropagated(string value, string expected) + { + Assert.Equal(expected, Render(value, 1234)); + } + + [Fact] + public void FormatProviderIsUsed() + { + var m = Render(new CultureInfo("fr-FR"), "Please pay {Sum}", 12.345); + Assert.Equal("Please pay 12,345", m); + } + + static string Render(string messageTemplate, params object[] properties) + { + return Render(null, messageTemplate, properties); + } + + static string Render(IFormatProvider? formatProvider, string messageTemplate, params object[] properties) + { + var binder = new LoggerConfiguration().CreateLogger(); + if (binder.BindMessageTemplate(messageTemplate, properties, out var mt, out var props) == false) + throw new InvalidOperationException(); + + var output = new StringBuilder(); + var writer = new StringWriter(output); + var renderer = new ThemedMessageTemplateRenderer(ConsoleTheme.None, + new ThemedDisplayValueFormatter(ConsoleTheme.None, formatProvider), false); + renderer.Render(mt, props.ToDictionary(p => p.Name, p => p.Value), writer); + writer.Flush(); + return output.ToString(); + } + + [Fact] + public void ATemplateWithOnlyPositionalPropertiesIsAnalyzedAndRenderedPositionally() + { + var m = Render("{1}, {0}", "world", "Hello"); + Assert.Equal("\"Hello\", \"world\"", m); + } + + [Fact] + public void ATemplateWithOnlyPositionalPropertiesUsesFormatProvider() + { + var m = Render(new CultureInfo("fr-FR"), "{1}, {0}", 12.345, "Hello"); + Assert.Equal("\"Hello\", 12,345", m); + } + + // Debatable what the behavior should be, here. + [Fact] + public void ATemplateWithNamesAndPositionalsUsesNamesForAllValues() + { + var m = Render("{1}, {Place}", "world", "Hello"); + Assert.Equal("\"world\", \"Hello\"", m); + } + + [Fact] + public void MissingPositionalParametersRenderAsTextLikeStandardFormats() + { + var m = Render("{1}, {0}", "world"); + Assert.Equal("{1}, \"world\"", m); + } + + [Fact] + public void AnonymousTypeShouldBeRendered() + { + var anonymous = new { Test = 3M }; + var m = Render("Anonymous type {value}", anonymous); + Assert.Equal("Anonymous type \"{ Test = 3 }\"", m); + } + + [Fact] + public void EnumerableOfAnonymousTypeShouldBeRendered() + { + var anonymous = new { Foo = 4M, Bar = "Baz" }; + var enumerable = Enumerable.Repeat("MyKey", 1).Select(v => anonymous); + var m = Render("Enumerable with anonymous type {enumerable}", enumerable); + Assert.Equal("Enumerable with anonymous type [\"{ Foo = 4, Bar = Baz }\"]", m); + } + + [Fact] + public void DictionaryOfAnonymousTypeAsValueShouldBeRendered() + { + var anonymous = new { Test = 5M }; + var dictionary = Enumerable.Repeat("MyKey", 1).ToDictionary(v => v, v => anonymous); + var m = Render("Dictionary with anonymous type value {dictionary}", dictionary); + Assert.Equal("Dictionary with anonymous type value {[\"MyKey\"]=\"{ Test = 5 }\"}", m); + } + + [Fact] + public void DictionaryOfAnonymousTypeAsKeyShouldBeRendered() + { + var anonymous = new { Bar = 6M, Baz = 4M }; + var dictionary = Enumerable.Repeat("MyValue", 1).ToDictionary(v => anonymous, v => v); + var m = Render("Dictionary with anonymous type key {dictionary}", dictionary); + Assert.Equal("Dictionary with anonymous type key [\"[{ Bar = 6, Baz = 4 }, MyValue]\"]", m); } } \ No newline at end of file diff --git a/test/Serilog.Sinks.Console.Tests/Support/DelegatingSink.cs b/test/Serilog.Sinks.Console.Tests/Support/DelegatingSink.cs index 1863a41..0f1495e 100644 --- a/test/Serilog.Sinks.Console.Tests/Support/DelegatingSink.cs +++ b/test/Serilog.Sinks.Console.Tests/Support/DelegatingSink.cs @@ -2,32 +2,31 @@ using Serilog.Core; using Serilog.Events; -namespace Serilog.Sinks.Console.Tests.Support +namespace Serilog.Sinks.Console.Tests.Support; + +public class DelegatingSink : ILogEventSink { - public class DelegatingSink : ILogEventSink - { - readonly Action _write; + readonly Action _write; - public DelegatingSink(Action write) - { - _write = write ?? throw new ArgumentNullException(nameof(write)); - } + public DelegatingSink(Action write) + { + _write = write ?? throw new ArgumentNullException(nameof(write)); + } - public void Emit(LogEvent logEvent) - { - _write(logEvent); - } + public void Emit(LogEvent logEvent) + { + _write(logEvent); + } - public static LogEvent GetLogEvent(Action writeAction) - { - LogEvent? result = null; - var logger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo.Sink(new DelegatingSink(le => result = le)) - .CreateLogger(); + public static LogEvent GetLogEvent(Action writeAction) + { + LogEvent? result = null; + var logger = new LoggerConfiguration() + .MinimumLevel.Verbose() + .WriteTo.Sink(new DelegatingSink(le => result = le)) + .CreateLogger(); - writeAction(logger); - return result!; - } + writeAction(logger); + return result!; } -} +} \ No newline at end of file diff --git a/test/Serilog.Sinks.Console.Tests/Support/TracingConsoleTheme.cs b/test/Serilog.Sinks.Console.Tests/Support/TracingConsoleTheme.cs index 901315e..93142a8 100644 --- a/test/Serilog.Sinks.Console.Tests/Support/TracingConsoleTheme.cs +++ b/test/Serilog.Sinks.Console.Tests/Support/TracingConsoleTheme.cs @@ -1,26 +1,25 @@ using System.IO; using Serilog.Sinks.SystemConsole.Themes; -namespace Serilog.Sinks.SystemConsole.Tests +namespace Serilog.Sinks.SystemConsole.Tests; + +class TracingConsoleTheme : ConsoleTheme { - class TracingConsoleTheme : ConsoleTheme - { - const string End = ""; + const string End = ""; - public override bool CanBuffer => true; + public override bool CanBuffer => true; - protected override int ResetCharCount { get; } = End.Length; + protected override int ResetCharCount { get; } = End.Length; - public override int Set(TextWriter output, ConsoleThemeStyle style) - { - var start = $"<{style.ToString().ToLowerInvariant()}>"; - output.Write(start); - return start.Length; - } + public override int Set(TextWriter output, ConsoleThemeStyle style) + { + var start = $"<{style.ToString().ToLowerInvariant()}>"; + output.Write(start); + return start.Length; + } - public override void Reset(TextWriter output) - { - output.Write(End); - } + public override void Reset(TextWriter output) + { + output.Write(End); } } \ No newline at end of file From c608cc9e9e65dc0b0052d37673ce687ab03bab39 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Fri, 7 Jun 2024 13:40:20 +1000 Subject: [PATCH 7/7] Sample targeting --- sample/ConsoleDemo/ConsoleDemo.csproj | 2 +- sample/ConsoleDemo/Program.cs | 46 +++++------- sample/SyncWritesDemo/Program.cs | 79 +++++++++------------ sample/SyncWritesDemo/SyncWritesDemo.csproj | 2 +- 4 files changed, 56 insertions(+), 73 deletions(-) diff --git a/sample/ConsoleDemo/ConsoleDemo.csproj b/sample/ConsoleDemo/ConsoleDemo.csproj index de9024a..67ca599 100644 --- a/sample/ConsoleDemo/ConsoleDemo.csproj +++ b/sample/ConsoleDemo/ConsoleDemo.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 diff --git a/sample/ConsoleDemo/Program.cs b/sample/ConsoleDemo/Program.cs index 3ff0ec4..6264faa 100644 --- a/sample/ConsoleDemo/Program.cs +++ b/sample/ConsoleDemo/Program.cs @@ -3,37 +3,29 @@ using System; using System.Threading; -namespace ConsoleDemo; +Log.Logger = new LoggerConfiguration() + .MinimumLevel.Verbose() + .WriteTo.Console(theme: AnsiConsoleTheme.Code) + .CreateLogger(); -public static class Program +try { - public static void Main() - { - Log.Logger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo.Console(theme: AnsiConsoleTheme.Code) - .CreateLogger(); + Log.Debug("Getting started"); - try - { - Log.Debug("Getting started"); + Log.Information("Hello {Name} from thread {ThreadId}", Environment.GetEnvironmentVariable("USERNAME"), Thread.CurrentThread.ManagedThreadId); - Log.Information("Hello {Name} from thread {ThreadId}", Environment.GetEnvironmentVariable("USERNAME"), Thread.CurrentThread.ManagedThreadId); + Log.Warning("No coins remain at position {@Position}", new { Lat = 25, Long = 134 }); - Log.Warning("No coins remain at position {@Position}", new { Lat = 25, Long = 134 }); - - Fail(); - } - catch (Exception e) - { - Log.Error(e, "Something went wrong"); - } + Fail(); +} +catch (Exception e) +{ + Log.Error(e, "Something went wrong"); +} - Log.CloseAndFlush(); - } +await Log.CloseAndFlushAsync(); - static void Fail() - { - throw new DivideByZeroException(); - } -} \ No newline at end of file +static void Fail() +{ + throw new DivideByZeroException(); +} diff --git a/sample/SyncWritesDemo/Program.cs b/sample/SyncWritesDemo/Program.cs index 3220c12..f1015a1 100644 --- a/sample/SyncWritesDemo/Program.cs +++ b/sample/SyncWritesDemo/Program.cs @@ -1,56 +1,47 @@ using Serilog; using Serilog.Sinks.SystemConsole.Themes; using System; -using System.Threading; using System.Threading.Tasks; -namespace SyncWritesDemo; +Console.WriteLine("A sample of how to sync writes to the console sink."); -public static class Program +if (args is { Length: 1 }) { - public static void Main(string[] args) + switch (args[0]) { - 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); + 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; } +} - 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(); +Console.WriteLine("Expecting one of the following arguments:{0}--sync-root-default{0}--sync-root-separate{0}--sync-root-same", Environment.NewLine); - var logger2 = new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("Logger", "logger2") - .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger2) - .CreateLogger(); +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 options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; - 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); - }); - } -} \ No newline at end of file + var logger2 = new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("Logger", "logger2") + .WriteTo.Console(theme: SystemConsoleTheme.Literate, syncRoot: syncRootForLogger2) + .CreateLogger(); + + var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; + Parallel.For(0, 1000, options, (i, _) => + { + var logger = i % 2 == 0 ? logger1 : logger2; + logger.Information("Event {Iteration} generated by {ThreadId}", i, Environment.CurrentManagedThreadId); + }); +} diff --git a/sample/SyncWritesDemo/SyncWritesDemo.csproj b/sample/SyncWritesDemo/SyncWritesDemo.csproj index de9024a..67ca599 100644 --- a/sample/SyncWritesDemo/SyncWritesDemo.csproj +++ b/sample/SyncWritesDemo/SyncWritesDemo.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0