diff --git a/sample/Sample/Program.cs b/sample/Sample/Program.cs index 898cddc..f2f15b5 100644 --- a/sample/Sample/Program.cs +++ b/sample/Sample/Program.cs @@ -3,6 +3,9 @@ using System.Threading; using Serilog; using Serilog.Core; +using Serilog.Debugging; + +SelfLog.Enable(Console.Error); // By sharing between the Seq sink and logger itself, // Seq API keys can be used to control the level of the whole logging pipeline. diff --git a/src/Serilog.Sinks.Seq/Serilog.Sinks.Seq.csproj b/src/Serilog.Sinks.Seq/Serilog.Sinks.Seq.csproj index 74e1f0c..6ffec04 100644 --- a/src/Serilog.Sinks.Seq/Serilog.Sinks.Seq.csproj +++ b/src/Serilog.Sinks.Seq/Serilog.Sinks.Seq.csproj @@ -29,9 +29,9 @@ - + - + diff --git a/src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/PreserveDottedPropertyNames.cs b/src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/PreserveDottedPropertyNames.cs index f25107c..523a84f 100644 --- a/src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/PreserveDottedPropertyNames.cs +++ b/src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/PreserveDottedPropertyNames.cs @@ -21,7 +21,7 @@ namespace Serilog.Sinks.Seq.Conventions; /// Maintains verbatim processing of property names. A property named "a.b" will be transmitted to Seq as a /// scalar value with name "a.b". /// -class PreserveDottedPropertyNames: IDottedPropertyNameConvention +sealed class PreserveDottedPropertyNames: IDottedPropertyNameConvention { /// public IReadOnlyDictionary ProcessDottedPropertyNames(IReadOnlyDictionary maybeDotted) diff --git a/src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/UnflattenDottedPropertyNames.cs b/src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/UnflattenDottedPropertyNames.cs index e3406ae..11fd55e 100644 --- a/src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/UnflattenDottedPropertyNames.cs +++ b/src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/UnflattenDottedPropertyNames.cs @@ -21,12 +21,12 @@ namespace Serilog.Sinks.Seq.Conventions; /// -/// Experimental. Unflatten property names. A property with name "a.b" will be transmitted to Seq as +/// Nest (un-flatten) properties with dotted names. A property with name "a.b" will be transmitted to Seq as /// a structure with name "a", and one member "b". /// /// This behavior is enabled when the Serilog.Parsing.MessageTemplateParser.AcceptDottedPropertyNames /// switch is set to value . -class UnflattenDottedPropertyNames: IDottedPropertyNameConvention +sealed class UnflattenDottedPropertyNames: IDottedPropertyNameConvention { const int MaxDepth = 10; diff --git a/src/Serilog.Sinks.Seq/Sinks/Seq/SeqCompactJsonFormatter.cs b/src/Serilog.Sinks.Seq/Sinks/Seq/SeqCompactJsonFormatter.cs index 22b059f..03e40fb 100644 --- a/src/Serilog.Sinks.Seq/Sinks/Seq/SeqCompactJsonFormatter.cs +++ b/src/Serilog.Sinks.Seq/Sinks/Seq/SeqCompactJsonFormatter.cs @@ -32,27 +32,27 @@ namespace Serilog.Sinks.Seq; /// /// Modified from Serilog.Formatting.Compact.CompactJsonFormatter to add /// implicit SerilogTracing span support. -public class SeqCompactJsonFormatter: ITextFormatter +public sealed class SeqCompactJsonFormatter: ITextFormatter { - readonly IDottedPropertyNameConvention _dottedPropertyNameConvention; readonly JsonValueFormatter _valueFormatter; readonly IFormatProvider _formatProvider; - + readonly IDottedPropertyNameConvention _dottedPropertyNameConvention; + /// /// Construct a . /// /// A value formatter for s on the event. /// An that will be used to render log event tokens. - public SeqCompactJsonFormatter(IFormatProvider? formatProvider = null, JsonValueFormatter? valueFormatter = null) + /// If , log event property names that + /// contain . will be sent to Seq as-is. Otherwise, properties with dotted names will be converted + /// into nested objects. + public SeqCompactJsonFormatter(IFormatProvider? formatProvider = null, JsonValueFormatter? valueFormatter = null, bool preserveDottedPropertyNames = false) { - var acceptDottedPropertyNames = AppContext.TryGetSwitch("Serilog.Parsing.MessageTemplateParser.AcceptDottedPropertyNames", out var accept) && accept; - - _dottedPropertyNameConvention = acceptDottedPropertyNames ? - new UnflattenDottedPropertyNames() : - new PreserveDottedPropertyNames(); - _formatProvider = formatProvider ?? CultureInfo.InvariantCulture; _valueFormatter = valueFormatter ?? new("$type"); + _dottedPropertyNameConvention = preserveDottedPropertyNames + ? new PreserveDottedPropertyNames() + : new UnflattenDottedPropertyNames(); } /// @@ -182,4 +182,4 @@ public void FormatEvent(LogEvent logEvent, TextWriter output) output.Write('}'); } -} \ No newline at end of file +} diff --git a/test/Serilog.Sinks.Seq.Tests/SeqCompactJsonFormatterTests.cs b/test/Serilog.Sinks.Seq.Tests/SeqCompactJsonFormatterTests.cs index 8ef87e6..c35b829 100644 --- a/test/Serilog.Sinks.Seq.Tests/SeqCompactJsonFormatterTests.cs +++ b/test/Serilog.Sinks.Seq.Tests/SeqCompactJsonFormatterTests.cs @@ -79,6 +79,14 @@ public void MultiplePropertiesAreDelimited() AssertValidJson(log => log.Information("Property {First} and {Second}", "One", "Two")); } + [Fact] + public void DottedPropertiesAreNested() + { + dynamic evt = AssertValidJson(log => log.Information("Property {a.b} and {a.c}", "One", "Two")); + Assert.Equal("One", (string)evt.a.b); + Assert.Equal("Two", (string)evt.a.c); + } + [Fact] public void ExceptionsAreFormattedToValidJson() {