From 49b7392a6e4dc49f0d1b439b8f1276ffd8d5b8ed Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Thu, 9 Nov 2023 16:57:14 +1000 Subject: [PATCH 1/5] Dev version bump [skip ci] --- .../Serilog.Formatting.Compact.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj b/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj index 06def8b..ccc3dd0 100644 --- a/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj +++ b/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj @@ -2,7 +2,7 @@ A simple, compact JSON-based event format for Serilog. - 2.0.0 + 2.0.1 Serilog Contributors net462;net471 $(TargetFrameworks);netstandard2.0;netstandard2.1;net6.0;net7.0 From c93ef5f0acbaa85e073e1ca5861d69dea5badeac Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Wed, 31 Jan 2024 11:23:57 +0300 Subject: [PATCH 2/5] Little cleanup --- .gitignore | 253 +----------------- Build.ps1 | 10 +- README.md | 2 + serilog-formatting-compact.sln | 10 +- serilog-formatting-compact.sln.DotSettings | 2 - .../Compact => }/CompactJsonFormatter.cs | 0 .../{Formatting/Compact => }/EventIdHash.cs | 6 +- .../Properties/AssemblyInfo.cs | 8 - .../RenderedCompactJsonFormatter.cs | 6 +- .../Serilog.Formatting.Compact.csproj | 4 +- .../FormattingBenchmarksConfig.cs | 2 +- 11 files changed, 25 insertions(+), 278 deletions(-) delete mode 100644 serilog-formatting-compact.sln.DotSettings rename src/Serilog.Formatting.Compact/{Formatting/Compact => }/CompactJsonFormatter.cs (100%) rename src/Serilog.Formatting.Compact/{Formatting/Compact => }/EventIdHash.cs (92%) delete mode 100644 src/Serilog.Formatting.Compact/Properties/AssemblyInfo.cs rename src/Serilog.Formatting.Compact/{Formatting/Compact => }/RenderedCompactJsonFormatter.cs (98%) diff --git a/.gitignore b/.gitignore index f1e3d20..2fad90d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,252 +1,5 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory .vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider .idea/ -*.sln.iml +obj/ +bin/ +*.user diff --git a/Build.ps1 b/Build.ps1 index 1178d7c..7256b6c 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -2,7 +2,7 @@ Write-Output "build: Build started" Push-Location $PSScriptRoot -if(Test-Path .\artifacts) { +if (Test-Path .\artifacts) { Write-Output "build: Cleaning .\artifacts" Remove-Item .\artifacts -Force -Recurse } @@ -18,18 +18,18 @@ Write-Output "build: Build version suffix is $buildSuffix" & dotnet build --configuration Release --version-suffix=$buildSuffix /p:ContinuousIntegrationBuild=true -if($LASTEXITCODE -ne 0) { throw 'build failed' } +if ($LASTEXITCODE -ne 0) { throw 'build failed' } -if($suffix) { +if ($suffix) { & dotnet pack src\Serilog.Formatting.Compact --configuration Release --no-build --no-restore -o artifacts --version-suffix=$suffix } else { & dotnet pack src\Serilog.Formatting.Compact --configuration Release --no-build --no-restore -o artifacts } -if($LASTEXITCODE -ne 0) { throw 'pack failed' } +if ($LASTEXITCODE -ne 0) { throw 'pack failed' } Write-Output "build: Testing" & dotnet test test\Serilog.Formatting.Compact.Tests --configuration Release --no-build --no-restore -if($LASTEXITCODE -ne 0) { throw 'unit tests failed' } +if ($LASTEXITCODE -ne 0) { throw 'unit tests failed' } diff --git a/README.md b/README.md index 730bd41..6d67a75 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,8 @@ The format defines a handful of reified properties that have special meaning: | `@x` | Exception | A language-dependent error representation potentially including backtrace | | | `@i` | Event id | An implementation specific event id (string or number) | | | `@r` | Renderings | If `@mt` includes tokens with programming-language-specific formatting, an array of pre-rendered values for each such token | May be omitted; if present, the count of renderings must match the count of formatted tokens exactly | +| `@tr` | Trace id | The id of the trace that was active when the event was created, if any | | +| `@sp` | Span id | The id of the span that was active when the event was created, if any | | The `@` sigil may be escaped at the start of a user property name by doubling, e.g. `@@name` denotes a property called `@name`. diff --git a/serilog-formatting-compact.sln b/serilog-formatting-compact.sln index c0f7b86..336cab0 100644 --- a/serilog-formatting-compact.sln +++ b/serilog-formatting-compact.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26114.2 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{037440DE-440B-4129-9F7A-09B42D00397E}" EndProject @@ -10,15 +10,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{E9D1B5 appveyor.yml = appveyor.yml Build.ps1 = Build.ps1 CHANGES.md = CHANGES.md + LICENSE = LICENSE README.md = README.md assets\Serilog.snk = assets\Serilog.snk + Setup.ps1 = Setup.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{67B1C971-75EE-4ABE-B184-66AAC8D9D572}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Formatting.Compact", "src\Serilog.Formatting.Compact\Serilog.Formatting.Compact.csproj", "{E0BB862A-8B2C-46B5-9C90-B2F94C32EAB3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Formatting.Compact", "src\Serilog.Formatting.Compact\Serilog.Formatting.Compact.csproj", "{E0BB862A-8B2C-46B5-9C90-B2F94C32EAB3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Formatting.Compact.Tests", "test\Serilog.Formatting.Compact.Tests\Serilog.Formatting.Compact.Tests.csproj", "{BAEECC42-EC0C-4955-8AA1-BD3F4F0F4AAD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Formatting.Compact.Tests", "test\Serilog.Formatting.Compact.Tests\Serilog.Formatting.Compact.Tests.csproj", "{BAEECC42-EC0C-4955-8AA1-BD3F4F0F4AAD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/serilog-formatting-compact.sln.DotSettings b/serilog-formatting-compact.sln.DotSettings deleted file mode 100644 index 72ec599..0000000 --- a/serilog-formatting-compact.sln.DotSettings +++ /dev/null @@ -1,2 +0,0 @@ - - DO_NOT_SHOW \ No newline at end of file diff --git a/src/Serilog.Formatting.Compact/Formatting/Compact/CompactJsonFormatter.cs b/src/Serilog.Formatting.Compact/CompactJsonFormatter.cs similarity index 100% rename from src/Serilog.Formatting.Compact/Formatting/Compact/CompactJsonFormatter.cs rename to src/Serilog.Formatting.Compact/CompactJsonFormatter.cs diff --git a/src/Serilog.Formatting.Compact/Formatting/Compact/EventIdHash.cs b/src/Serilog.Formatting.Compact/EventIdHash.cs similarity index 92% rename from src/Serilog.Formatting.Compact/Formatting/Compact/EventIdHash.cs rename to src/Serilog.Formatting.Compact/EventIdHash.cs index 8c4dcdc..51be4a0 100644 --- a/src/Serilog.Formatting.Compact/Formatting/Compact/EventIdHash.cs +++ b/src/Serilog.Formatting.Compact/EventIdHash.cs @@ -22,9 +22,9 @@ namespace Serilog.Formatting.Compact public static class EventIdHash { /// - /// Compute a 32-bit hash of the provided . The - /// resulting hash value can be uses as an event id in lieu of transmitting the - /// full template string. + /// Compute a 32-bit hash of the provided . + /// The resulting hash value can be uses as an event id in lieu of transmitting + /// the full template string. /// /// A message template. /// A 32-bit hash of the template. diff --git a/src/Serilog.Formatting.Compact/Properties/AssemblyInfo.cs b/src/Serilog.Formatting.Compact/Properties/AssemblyInfo.cs deleted file mode 100644 index 72c1391..0000000 --- a/src/Serilog.Formatting.Compact/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("Serilog.Formatting.Compact.Tests, PublicKey=" + - "0024000004800000940000000602000000240000525341310004000001000100fb8d13fd344a1c" + - "6fe0fe83ef33c1080bf30690765bc6eb0df26ebfdf8f21670c64265b30db09f73a0dea5b3db4c9" + - "d18dbf6d5a25af5ce9016f281014d79dc3b4201ac646c451830fc7e61a2dfd633d34c39f87b818" + - "94191652df5ac63cc40c77f3542f702bda692e6e8a9158353df189007a49da0f3cfd55eb250066" + - "b19485ec")] diff --git a/src/Serilog.Formatting.Compact/Formatting/Compact/RenderedCompactJsonFormatter.cs b/src/Serilog.Formatting.Compact/RenderedCompactJsonFormatter.cs similarity index 98% rename from src/Serilog.Formatting.Compact/Formatting/Compact/RenderedCompactJsonFormatter.cs rename to src/Serilog.Formatting.Compact/RenderedCompactJsonFormatter.cs index fbe0dd2..327cebc 100644 --- a/src/Serilog.Formatting.Compact/Formatting/Compact/RenderedCompactJsonFormatter.cs +++ b/src/Serilog.Formatting.Compact/RenderedCompactJsonFormatter.cs @@ -22,7 +22,7 @@ namespace Serilog.Formatting.Compact { /// - /// An that writes events in a compact JSON format, for consumption in environments + /// An that writes events in a compact JSON format, for consumption in environments /// without message template support. Message templates are rendered into text and a hashed event id is included. /// public class RenderedCompactJsonFormatter : ITextFormatter @@ -84,7 +84,7 @@ public static void FormatEvent(LogEvent logEvent, TextWriter output, JsonValueFo output.Write(",\"@x\":"); JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output); } - + if (logEvent.TraceId != null) { output.Write(",\"@tr\":\""); @@ -98,7 +98,7 @@ public static void FormatEvent(LogEvent logEvent, TextWriter output, JsonValueFo output.Write(logEvent.SpanId.Value.ToHexString()); output.Write('\"'); } - + foreach (var property in logEvent.Properties) { var name = property.Key; diff --git a/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj b/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj index ccc3dd0..8ba4ecd 100644 --- a/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj +++ b/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj @@ -1,4 +1,4 @@ - + A simple, compact JSON-based event format for Serilog. @@ -19,7 +19,6 @@ https://github.com/serilog/serilog-formatting-compact git 6.0-recommended - Serilog README.md @@ -31,6 +30,7 @@ + diff --git a/test/Serilog.Formatting.Compact.Tests/FormattingBenchmarksConfig.cs b/test/Serilog.Formatting.Compact.Tests/FormattingBenchmarksConfig.cs index b0bcddd..e61aaa6 100644 --- a/test/Serilog.Formatting.Compact.Tests/FormattingBenchmarksConfig.cs +++ b/test/Serilog.Formatting.Compact.Tests/FormattingBenchmarksConfig.cs @@ -7,7 +7,7 @@ public class FormattingBenchmarksConfig : ManualConfig { public FormattingBenchmarksConfig() { - this.AddJob(Job.Default.WithIterationCount(10)); + AddJob(Job.Default.WithIterationCount(10)); } } } \ No newline at end of file From 9a787126be77656b6a73efd8e01384cc7e91225b Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Wed, 31 Jan 2024 11:27:10 +0300 Subject: [PATCH 3/5] indent --- .../Serilog.Formatting.Compact.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj b/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj index 8ba4ecd..be739d6 100644 --- a/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj +++ b/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj @@ -30,7 +30,7 @@ - + From 0bbaf22f5c3c3a0a209d4e2f266e3191e5ca88d0 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Fri, 7 Jun 2024 14:32:12 +1000 Subject: [PATCH 4/5] Update to Serilog 4 --- README.md | 7 +- global.json | 5 - .../CompactJsonFormatter.cs | 184 +++++++++--------- src/Serilog.Formatting.Compact/EventIdHash.cs | 53 +++-- .../RenderedCompactJsonFormatter.cs | 159 ++++++++------- .../Serilog.Formatting.Compact.csproj | 9 +- .../Serilog.Formatting.Compact.Tests.csproj | 2 +- 7 files changed, 209 insertions(+), 210 deletions(-) delete mode 100644 global.json diff --git a/README.md b/README.md index 6d67a75..3328f27 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ A simple `Hello, {User}` event. Install from [NuGet](https://nuget.org/packages/Serilog.Formatting.Compact): ```powershell -Install-Package Serilog.Formatting.Compact +dotnet add package Serilog.Formatting.Compact ``` The formatter is used in conjunction with sinks that accept `ITextFormatter`. For example, the [file](https://github.com/serilog/serilog-sinks-file) sink: @@ -26,6 +26,7 @@ Log.Logger = new LoggerConfiguration() .CreateLogger(); ``` #### XML `` configuration + To specify the formatter in XML `` provide its assembly-qualified type name: ```xml @@ -154,3 +155,7 @@ Several tools are available for working with the CLEF format. * **[Compact Log Format Viewer](https://github.com/warrenbuckley/Compact-Log-Format-Viewer)** - a cross-platform viewer for CLEF files * **[`seqcli`](https://github.com/datalust/seqcli)** - pretty-`print` CLEF files at the command-line, or `ingest` CLEF files into [Seq](https://datalust.co/seq) for search, and analysis * **[_Serilog.Formatting.Compact.Reader_](https://github.com/serilog/serilog-formatting-compact-reader)** - convert CLEF documents back into Serilog `LogEvent`s + +### Customizing output + +_Serilog.Formatting.Compact_ is not intended to provide customizable formatters. See [this blog post](https://nblumhardt.com/2021/06/customize-serilog-json-output/) for comprehensive Serilog JSON output customization examples. diff --git a/global.json b/global.json deleted file mode 100644 index 8960f9e..0000000 --- a/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "7.0.304" - } -} \ No newline at end of file diff --git a/src/Serilog.Formatting.Compact/CompactJsonFormatter.cs b/src/Serilog.Formatting.Compact/CompactJsonFormatter.cs index 992740c..8299e75 100644 --- a/src/Serilog.Formatting.Compact/CompactJsonFormatter.cs +++ b/src/Serilog.Formatting.Compact/CompactJsonFormatter.cs @@ -21,117 +21,117 @@ using Serilog.Parsing; // ReSharper disable MemberCanBePrivate.Global -namespace Serilog.Formatting.Compact +namespace Serilog.Formatting.Compact; + +/// +/// An that writes events in a compact JSON format. +/// +public class CompactJsonFormatter: ITextFormatter { + readonly JsonValueFormatter _valueFormatter; + /// - /// An that writes events in a compact JSON format. + /// Construct a , optionally supplying a formatter for + /// s on the event. /// - public class CompactJsonFormatter: ITextFormatter + /// A value formatter, or null. + public CompactJsonFormatter(JsonValueFormatter? valueFormatter = null) { - readonly JsonValueFormatter _valueFormatter; - - /// - /// Construct a , optionally supplying a formatter for - /// s on the event. - /// - /// A value formatter, or null. - public CompactJsonFormatter(JsonValueFormatter valueFormatter = null) - { - _valueFormatter = valueFormatter ?? new JsonValueFormatter(typeTagName: "$type"); - } + _valueFormatter = valueFormatter ?? new JsonValueFormatter(typeTagName: "$type"); + } - /// - /// Format the log event into the output. Subsequent events will be newline-delimited. - /// - /// The event to format. - /// The output. - public void Format(LogEvent logEvent, TextWriter output) - { - FormatEvent(logEvent, output, _valueFormatter); - output.WriteLine(); - } + /// + /// Format the log event into the output. Subsequent events will be newline-delimited. + /// + /// The event to format. + /// The output. + public void Format(LogEvent logEvent, TextWriter output) + { + FormatEvent(logEvent, output, _valueFormatter); + output.WriteLine(); + } - /// - /// Format the log event into the output. - /// - /// The event to format. - /// The output. - /// A value formatter for s on the event. - public static void FormatEvent(LogEvent logEvent, TextWriter output, JsonValueFormatter valueFormatter) - { - if (logEvent == null) throw new ArgumentNullException(nameof(logEvent)); - if (output == null) throw new ArgumentNullException(nameof(output)); - if (valueFormatter == null) throw new ArgumentNullException(nameof(valueFormatter)); + /// + /// Format the log event into the output. + /// + /// The event to format. + /// The output. + /// A value formatter for s on the event. + public static void FormatEvent(LogEvent logEvent, TextWriter output, JsonValueFormatter valueFormatter) + { + if (logEvent == null) throw new ArgumentNullException(nameof(logEvent)); + if (output == null) throw new ArgumentNullException(nameof(output)); + if (valueFormatter == null) throw new ArgumentNullException(nameof(valueFormatter)); - output.Write("{\"@t\":\""); - output.Write(logEvent.Timestamp.UtcDateTime.ToString("O")); - output.Write("\",\"@mt\":"); - JsonValueFormatter.WriteQuotedJsonString(logEvent.MessageTemplate.Text, output); + output.Write("{\"@t\":\""); + output.Write(logEvent.Timestamp.UtcDateTime.ToString("O")); + output.Write("\",\"@mt\":"); + JsonValueFormatter.WriteQuotedJsonString(logEvent.MessageTemplate.Text, output); - var tokensWithFormat = logEvent.MessageTemplate.Tokens - .OfType() - .Where(pt => pt.Format != null); + var tokensWithFormat = logEvent.MessageTemplate.Tokens + .OfType() + .Where(pt => pt.Format != null); - // Better not to allocate an array in the 99.9% of cases where this is false + // Better not to allocate an array in the 99.9% of cases where this is false + // ReSharper disable once PossibleMultipleEnumeration + if (tokensWithFormat.Any()) + { + output.Write(",\"@r\":["); + var delim = ""; // ReSharper disable once PossibleMultipleEnumeration - if (tokensWithFormat.Any()) + foreach (var r in tokensWithFormat) { - output.Write(",\"@r\":["); - var delim = ""; - foreach (PropertyToken r in tokensWithFormat) - { - output.Write(delim); - delim = ","; - var space = new StringWriter(); - r.Render(logEvent.Properties, space, CultureInfo.InvariantCulture); - JsonValueFormatter.WriteQuotedJsonString(space.ToString(), output); - } - output.Write(']'); + output.Write(delim); + delim = ","; + var space = new StringWriter(); + r.Render(logEvent.Properties, space, CultureInfo.InvariantCulture); + JsonValueFormatter.WriteQuotedJsonString(space.ToString(), output); } + output.Write(']'); + } - if (logEvent.Level != LogEventLevel.Information) - { - output.Write(",\"@l\":\""); - output.Write(logEvent.Level); - output.Write('\"'); - } + if (logEvent.Level != LogEventLevel.Information) + { + output.Write(",\"@l\":\""); + output.Write(logEvent.Level); + output.Write('\"'); + } - if (logEvent.Exception != null) - { - output.Write(",\"@x\":"); - JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output); - } + if (logEvent.Exception != null) + { + output.Write(",\"@x\":"); + JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output); + } - if (logEvent.TraceId != null) - { - output.Write(",\"@tr\":\""); - output.Write(logEvent.TraceId.Value.ToHexString()); - output.Write('\"'); - } + if (logEvent.TraceId != null) + { + output.Write(",\"@tr\":\""); + output.Write(logEvent.TraceId.Value.ToHexString()); + output.Write('\"'); + } - if (logEvent.SpanId != null) - { - output.Write(",\"@sp\":\""); - output.Write(logEvent.SpanId.Value.ToHexString()); - output.Write('\"'); - } + if (logEvent.SpanId != null) + { + output.Write(",\"@sp\":\""); + output.Write(logEvent.SpanId.Value.ToHexString()); + output.Write('\"'); + } - foreach (var property in logEvent.Properties) + foreach (var property in logEvent.Properties) + { + var name = property.Key; + if (name.Length > 0 && name[0] == '@') { - var name = property.Key; - if (name.Length > 0 && name[0] == '@') - { - // Escape first '@' by doubling - name = '@' + name; - } - - output.Write(','); - JsonValueFormatter.WriteQuotedJsonString(name, output); - output.Write(':'); - valueFormatter.Format(property.Value, output); + // Escape first '@' by doubling + name = '@' + name; } - output.Write('}'); + output.Write(','); + JsonValueFormatter.WriteQuotedJsonString(name, output); + output.Write(':'); + valueFormatter.Format(property.Value, output); } + + output.Write('}'); } -} +} \ No newline at end of file diff --git a/src/Serilog.Formatting.Compact/EventIdHash.cs b/src/Serilog.Formatting.Compact/EventIdHash.cs index 51be4a0..786aac7 100644 --- a/src/Serilog.Formatting.Compact/EventIdHash.cs +++ b/src/Serilog.Formatting.Compact/EventIdHash.cs @@ -14,39 +14,38 @@ using System; -namespace Serilog.Formatting.Compact +namespace Serilog.Formatting.Compact; + +/// +/// Hash functions for message templates. See . +/// +public static class EventIdHash { /// - /// Hash functions for message templates. See . + /// Compute a 32-bit hash of the provided . + /// The resulting hash value can be uses as an event id in lieu of transmitting + /// the full template string. /// - public static class EventIdHash + /// A message template. + /// A 32-bit hash of the template. + public static uint Compute(string messageTemplate) { - /// - /// Compute a 32-bit hash of the provided . - /// The resulting hash value can be uses as an event id in lieu of transmitting - /// the full template string. - /// - /// A message template. - /// A 32-bit hash of the template. - public static uint Compute(string messageTemplate) - { - if (messageTemplate == null) throw new ArgumentNullException(nameof(messageTemplate)); + if (messageTemplate == null) throw new ArgumentNullException(nameof(messageTemplate)); - // Jenkins one-at-a-time https://en.wikipedia.org/wiki/Jenkins_hash_function - unchecked + // Jenkins one-at-a-time https://en.wikipedia.org/wiki/Jenkins_hash_function + unchecked + { + uint hash = 0; + for (var i = 0; i < messageTemplate.Length; ++i) { - uint hash = 0; - for (var i = 0; i < messageTemplate.Length; ++i) - { - hash += messageTemplate[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; + hash += messageTemplate[i]; + hash += (hash << 10); + hash ^= (hash >> 6); } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; } } -} +} \ No newline at end of file diff --git a/src/Serilog.Formatting.Compact/RenderedCompactJsonFormatter.cs b/src/Serilog.Formatting.Compact/RenderedCompactJsonFormatter.cs index 327cebc..075a729 100644 --- a/src/Serilog.Formatting.Compact/RenderedCompactJsonFormatter.cs +++ b/src/Serilog.Formatting.Compact/RenderedCompactJsonFormatter.cs @@ -19,102 +19,101 @@ using Serilog.Formatting.Json; // ReSharper disable MemberCanBePrivate.Global -namespace Serilog.Formatting.Compact +namespace Serilog.Formatting.Compact; + +/// +/// An that writes events in a compact JSON format, for consumption in environments +/// without message template support. Message templates are rendered into text and a hashed event id is included. +/// +public class RenderedCompactJsonFormatter : ITextFormatter { + readonly JsonValueFormatter _valueFormatter; + + /// + /// Construct a , optionally supplying a formatter for + /// s on the event. + /// + /// A value formatter, or null. + public RenderedCompactJsonFormatter(JsonValueFormatter? valueFormatter = null) + { + _valueFormatter = valueFormatter ?? new JsonValueFormatter(typeTagName: "$type"); + } + + /// + /// Format the log event into the output. Subsequent events will be newline-delimited. + /// + /// The event to format. + /// The output. + public void Format(LogEvent logEvent, TextWriter output) + { + FormatEvent(logEvent, output, _valueFormatter); + output.WriteLine(); + } + /// - /// An that writes events in a compact JSON format, for consumption in environments - /// without message template support. Message templates are rendered into text and a hashed event id is included. + /// Format the log event into the output. /// - public class RenderedCompactJsonFormatter : ITextFormatter + /// The event to format. + /// The output. + /// A value formatter for s on the event. + public static void FormatEvent(LogEvent logEvent, TextWriter output, JsonValueFormatter valueFormatter) { - readonly JsonValueFormatter _valueFormatter; + if (logEvent == null) throw new ArgumentNullException(nameof(logEvent)); + if (output == null) throw new ArgumentNullException(nameof(output)); + if (valueFormatter == null) throw new ArgumentNullException(nameof(valueFormatter)); - /// - /// Construct a , optionally supplying a formatter for - /// s on the event. - /// - /// A value formatter, or null. - public RenderedCompactJsonFormatter(JsonValueFormatter valueFormatter = null) + output.Write("{\"@t\":\""); + output.Write(logEvent.Timestamp.UtcDateTime.ToString("O")); + output.Write("\",\"@m\":"); + var message = logEvent.MessageTemplate.Render(logEvent.Properties, CultureInfo.InvariantCulture); + JsonValueFormatter.WriteQuotedJsonString(message, output); + output.Write(",\"@i\":\""); + var id = EventIdHash.Compute(logEvent.MessageTemplate.Text); + output.Write(id.ToString("x8",CultureInfo.InvariantCulture)); + output.Write('"'); + + if (logEvent.Level != LogEventLevel.Information) { - _valueFormatter = valueFormatter ?? new JsonValueFormatter(typeTagName: "$type"); + output.Write(",\"@l\":\""); + output.Write(logEvent.Level); + output.Write('\"'); } - /// - /// Format the log event into the output. Subsequent events will be newline-delimited. - /// - /// The event to format. - /// The output. - public void Format(LogEvent logEvent, TextWriter output) + if (logEvent.Exception != null) { - FormatEvent(logEvent, output, _valueFormatter); - output.WriteLine(); + output.Write(",\"@x\":"); + JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output); } - /// - /// Format the log event into the output. - /// - /// The event to format. - /// The output. - /// A value formatter for s on the event. - public static void FormatEvent(LogEvent logEvent, TextWriter output, JsonValueFormatter valueFormatter) + if (logEvent.TraceId != null) { - if (logEvent == null) throw new ArgumentNullException(nameof(logEvent)); - if (output == null) throw new ArgumentNullException(nameof(output)); - if (valueFormatter == null) throw new ArgumentNullException(nameof(valueFormatter)); - - output.Write("{\"@t\":\""); - output.Write(logEvent.Timestamp.UtcDateTime.ToString("O")); - output.Write("\",\"@m\":"); - var message = logEvent.MessageTemplate.Render(logEvent.Properties, CultureInfo.InvariantCulture); - JsonValueFormatter.WriteQuotedJsonString(message, output); - output.Write(",\"@i\":\""); - var id = EventIdHash.Compute(logEvent.MessageTemplate.Text); - output.Write(id.ToString("x8",CultureInfo.InvariantCulture)); - output.Write('"'); - - if (logEvent.Level != LogEventLevel.Information) - { - output.Write(",\"@l\":\""); - output.Write(logEvent.Level); - output.Write('\"'); - } - - if (logEvent.Exception != null) - { - output.Write(",\"@x\":"); - JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output); - } - - if (logEvent.TraceId != null) - { - output.Write(",\"@tr\":\""); - output.Write(logEvent.TraceId.Value.ToHexString()); - output.Write('\"'); - } + output.Write(",\"@tr\":\""); + output.Write(logEvent.TraceId.Value.ToHexString()); + output.Write('\"'); + } - if (logEvent.SpanId != null) - { - output.Write(",\"@sp\":\""); - output.Write(logEvent.SpanId.Value.ToHexString()); - output.Write('\"'); - } + if (logEvent.SpanId != null) + { + output.Write(",\"@sp\":\""); + output.Write(logEvent.SpanId.Value.ToHexString()); + output.Write('\"'); + } - foreach (var property in logEvent.Properties) + foreach (var property in logEvent.Properties) + { + var name = property.Key; + if (name.Length > 0 && name[0] == '@') { - var name = property.Key; - if (name.Length > 0 && name[0] == '@') - { - // Escape first '@' by doubling - name = '@' + name; - } - - output.Write(','); - JsonValueFormatter.WriteQuotedJsonString(name, output); - output.Write(':'); - valueFormatter.Format(property.Value, output); + // Escape first '@' by doubling + name = '@' + name; } - output.Write('}'); + output.Write(','); + JsonValueFormatter.WriteQuotedJsonString(name, output); + output.Write(':'); + valueFormatter.Format(property.Value, output); } + + output.Write('}'); } -} +} \ No newline at end of file diff --git a/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj b/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj index be739d6..64aa9fb 100644 --- a/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj +++ b/src/Serilog.Formatting.Compact/Serilog.Formatting.Compact.csproj @@ -2,10 +2,10 @@ A simple, compact JSON-based event format for Serilog. - 2.0.1 + 3.0.0 Serilog Contributors net462;net471 - $(TargetFrameworks);netstandard2.0;netstandard2.1;net6.0;net7.0 + $(TargetFrameworks);netstandard2.0;net6.0;net8.0 true true ../../assets/Serilog.snk @@ -15,11 +15,12 @@ serilog;json https://github.com/serilog/serilog-formatting-compact Apache-2.0 - True https://github.com/serilog/serilog-formatting-compact git 6.0-recommended README.md + enable + 12 @@ -27,7 +28,7 @@ - + diff --git a/test/Serilog.Formatting.Compact.Tests/Serilog.Formatting.Compact.Tests.csproj b/test/Serilog.Formatting.Compact.Tests/Serilog.Formatting.Compact.Tests.csproj index 6a3a324..20f010c 100644 --- a/test/Serilog.Formatting.Compact.Tests/Serilog.Formatting.Compact.Tests.csproj +++ b/test/Serilog.Formatting.Compact.Tests/Serilog.Formatting.Compact.Tests.csproj @@ -2,7 +2,7 @@ net462;net48 - $(TargetFrameworks);netcoreapp3.1;net6.0;net7.0; + $(TargetFrameworks);net6.0;net8.0; Serilog.Formatting.Compact.Tests ../../assets/Serilog.snk true From 35d4901af4c471fc997abd98bba1860b76b8fdee Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Fri, 7 Jun 2024 14:43:28 +1000 Subject: [PATCH 5/5] Don't pin SDK version, this just tends to mean we're running an outdated one --- appveyor.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3022cf7..1163cae 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,10 +2,8 @@ version: '{build}' skip_tags: true image: Visual Studio 2022 configuration: Release -install: - - ps: ./Setup.ps1 build_script: -- ps: ./Build.ps1 +- pwsh: ./Build.ps1 test: false artifacts: - path: artifacts/Serilog.*.nupkg