From 32eea6c84b006ce1dda8f12ff7b40ad011af664b Mon Sep 17 00:00:00 2001 From: Gianni Bonicolini Date: Fri, 24 Oct 2025 09:15:03 +0200 Subject: [PATCH] Added default value when field doesn't allow null --- .../Output/StandardColumnDataGenerator.cs | 9 ++- .../StandardColumnDataGeneratorTests.cs | 63 +++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/Output/StandardColumnDataGenerator.cs b/src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/Output/StandardColumnDataGenerator.cs index 938b5271..ff090665 100644 --- a/src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/Output/StandardColumnDataGenerator.cs +++ b/src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/Output/StandardColumnDataGenerator.cs @@ -51,13 +51,16 @@ public KeyValuePair GetStandardColumnNameAndValue(StandardColumn case StandardColumn.Level: return new KeyValuePair(_columnOptions.Level.ColumnName, _columnOptions.Level.StoreAsEnum ? (object)logEvent.Level : logEvent.Level.ToString()); case StandardColumn.TraceId: - return new KeyValuePair(_columnOptions.TraceId.ColumnName, logEvent.TraceId?.ToString()); + var userDefaultTraceIdValue = logEvent.TraceId is null && !_columnOptions.TraceId.AllowNull; + return new KeyValuePair(_columnOptions.TraceId.ColumnName, userDefaultTraceIdValue ? _columnOptions.TraceId.AsDataColumn().DefaultValue.ToString() : logEvent.TraceId?.ToString()); case StandardColumn.SpanId: - return new KeyValuePair(_columnOptions.SpanId.ColumnName, logEvent.SpanId?.ToString()); + var userDefaultSpanIdValue = logEvent.SpanId is null && !_columnOptions.SpanId.AllowNull; + return new KeyValuePair(_columnOptions.SpanId.ColumnName, userDefaultSpanIdValue ? _columnOptions.SpanId.AsDataColumn().DefaultValue.ToString() : logEvent.SpanId?.ToString()); case StandardColumn.TimeStamp: return GetTimeStampStandardColumnNameAndValue(logEvent); case StandardColumn.Exception: - return new KeyValuePair(_columnOptions.Exception.ColumnName, logEvent.Exception?.ToString().TruncateOutput(_columnOptions.Exception.DataLength)); + var userDefaultExceptionValue = logEvent.Exception is null && !_columnOptions.Exception.AllowNull; + return new KeyValuePair(_columnOptions.Exception.ColumnName, userDefaultExceptionValue ? _columnOptions.Exception.AsDataColumn().DefaultValue.ToString() : logEvent.Exception?.ToString().TruncateOutput(_columnOptions.Exception.DataLength)); case StandardColumn.Properties: return new KeyValuePair(_columnOptions.Properties.ColumnName, ConvertPropertiesToXmlStructure(logEvent.Properties)); case StandardColumn.LogEvent: diff --git a/test/Serilog.Sinks.MSSqlServer.Tests/Sinks/MSSqlServer/Output/StandardColumnDataGeneratorTests.cs b/test/Serilog.Sinks.MSSqlServer.Tests/Sinks/MSSqlServer/Output/StandardColumnDataGeneratorTests.cs index 87ef6023..9c0b3265 100644 --- a/test/Serilog.Sinks.MSSqlServer.Tests/Sinks/MSSqlServer/Output/StandardColumnDataGeneratorTests.cs +++ b/test/Serilog.Sinks.MSSqlServer.Tests/Sinks/MSSqlServer/Output/StandardColumnDataGeneratorTests.cs @@ -301,6 +301,27 @@ public void GetStandardColumnNameAndNullValueForTraceIdReturnsLogLevelKeyValue() Assert.Null(result.Value); } + [Fact] + public void GetStandardColumnNameAndNullValueForTraceIdWithoutAllowNullReturnsLogLevelKeyValueEmpty() + { + // Arrange + var traceId = default(ActivityTraceId); + var logEvent = new LogEvent( + new DateTimeOffset(2020, 1, 1, 0, 0, 0, 0, TimeSpan.Zero), + LogEventLevel.Debug, null, new MessageTemplate(new List() { new TextToken("Test message") }), + new List(), traceId, ActivitySpanId.CreateRandom()); + var columnOptions = new MSSqlServer.ColumnOptions(); + columnOptions.TraceId.AllowNull = false; + SetupSut(columnOptions, CultureInfo.InvariantCulture); + + // Act + var result = _sut.GetStandardColumnNameAndValue(StandardColumn.TraceId, logEvent); + + // Assert + Assert.Equal("TraceId", result.Key); + Assert.Equal(string.Empty, result.Value); + } + [Fact] public void GetStandardColumnNameAndValueForSpanIdReturnsLogLevelKeyValue() { @@ -339,6 +360,27 @@ public void GetStandardColumnNameAndNullValueForSpanIdReturnsLogLevelKeyValue() Assert.Null(result.Value); } + [Fact] + public void GetStandardColumnNameAndNullValueForSpanIdWithoutAllowNullReturnsLogLevelKeyValueEmpty() + { + // Arrange + var spanId = default(ActivitySpanId); + var logEvent = new LogEvent( + new DateTimeOffset(2020, 1, 1, 0, 0, 0, 0, TimeSpan.Zero), + LogEventLevel.Debug, null, new MessageTemplate(new List() { new TextToken("Test message") }), + new List(), ActivityTraceId.CreateRandom(), spanId); + var columnOptions = new MSSqlServer.ColumnOptions(); + columnOptions.SpanId.AllowNull = false; + SetupSut(columnOptions, CultureInfo.InvariantCulture); + + // Act + var result = _sut.GetStandardColumnNameAndValue(StandardColumn.SpanId, logEvent); + + // Assert + Assert.Equal("SpanId", result.Key); + Assert.Equal(string.Empty, result.Value); + } + [Fact] public void GetStandardColumnNameAndValueForLogLevelReturnsLogLevelKeyValueAsEnum() { @@ -487,6 +529,27 @@ public void GetStandardColumnNameAndValueForExceptionWhenCalledWithoutExceptionR Assert.Null(result.Value); } + [Fact] + public void GetStandardColumnNameAndValueForExceptionWhenCalledWithoutExceptionAndNotAllowedNullReturnsEmptyValue() + { + // Arrange + var logEvent = new LogEvent( + new DateTimeOffset(2020, 1, 1, 0, 0, 0, 0, TimeSpan.Zero), + LogEventLevel.Debug, null, new MessageTemplate(new List() { new TextToken("Test message") }), + new List()); + var columnOptions = new Serilog.Sinks.MSSqlServer.ColumnOptions(); + columnOptions.Level.StoreAsEnum = true; + columnOptions.Exception.AllowNull = false; + SetupSut(columnOptions, CultureInfo.InvariantCulture); + + // Act + var result = _sut.GetStandardColumnNameAndValue(StandardColumn.Exception, logEvent); + + // Assert + Assert.Equal("Exception", result.Key); + Assert.Equal(string.Empty, result.Value); + } + [Fact] public void GetStandardColumnNameAndValueForPropertiesUsesRootElementName() {