Skip to content

Commit 322c5f2

Browse files
committed
SerilogLoggerScope add support for ValueTuple<string, object?> state. Add SerilogLoggerScopeTests.
1 parent 80064f8 commit 322c5f2

File tree

3 files changed

+127
-5
lines changed

3 files changed

+127
-5
lines changed

src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLoggerScope.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ public void Dispose()
4949

5050
public void EnrichAndCreateScopeItem(LogEvent logEvent, ILogEventPropertyFactory propertyFactory, out LogEventPropertyValue? scopeItem)
5151
{
52-
void AddProperty(KeyValuePair<string, object> stateProperty)
52+
void AddProperty(string key, object? value)
5353
{
54-
var key = stateProperty.Key;
5554
var destructureObject = false;
56-
var value = stateProperty.Value;
5755

5856
if (key.StartsWith("@"))
5957
{
@@ -86,7 +84,7 @@ void AddProperty(KeyValuePair<string, object> stateProperty)
8684
if (stateProperty.Key == SerilogLoggerProvider.OriginalFormatPropertyName && stateProperty.Value is string)
8785
scopeItem = new ScalarValue(_state.ToString());
8886
else
89-
AddProperty(stateProperty);
87+
AddProperty(stateProperty.Key, stateProperty.Value);
9088
}
9189
}
9290
else if (_state is IEnumerable<KeyValuePair<string, object>> stateProperties)
@@ -98,9 +96,18 @@ void AddProperty(KeyValuePair<string, object> stateProperty)
9896
if (stateProperty.Key == SerilogLoggerProvider.OriginalFormatPropertyName && stateProperty.Value is string)
9997
scopeItem = new ScalarValue(_state.ToString());
10098
else
101-
AddProperty(stateProperty);
99+
AddProperty(stateProperty.Key, stateProperty.Value);
102100
}
103101
}
102+
else if (_state is ValueTuple<string, object?> tuple)
103+
{
104+
scopeItem = null; // Unless it's `FormattedLogValues`, these are treated as property bags rather than scope items.
105+
106+
if (tuple.Item1 == SerilogLoggerProvider.OriginalFormatPropertyName && tuple.Item2 is string)
107+
scopeItem = new ScalarValue(_state.ToString());
108+
else
109+
AddProperty(tuple.Item1, tuple.Item2);
110+
}
104111
else
105112
{
106113
scopeItem = propertyFactory.CreateProperty(NoName, _state).Value;
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Serilog.Events;
5+
using Serilog.Extensions.Logging.Tests.Support;
6+
7+
using Xunit;
8+
9+
namespace Serilog.Extensions.Logging.Tests;
10+
public class SerilogLoggerScopeTests
11+
{
12+
static (SerilogLoggerProvider, LogEventPropertyFactory, LogEvent) SetUp()
13+
{
14+
var loggerProvider = new SerilogLoggerProvider();
15+
16+
var logEventPropertyFactory = new LogEventPropertyFactory();
17+
18+
var dateTimeOffset = new DateTimeOffset(2000, 1, 1, 0, 0, 0, TimeSpan.Zero);
19+
var messageTemplate = new MessageTemplate(Enumerable.Empty<Parsing.MessageTemplateToken>());
20+
var properties = Enumerable.Empty<LogEventProperty>();
21+
var logEvent = new LogEvent(dateTimeOffset, LogEventLevel.Information, null, messageTemplate, properties);
22+
23+
return (loggerProvider, logEventPropertyFactory, logEvent);
24+
}
25+
26+
[Fact]
27+
public void EnrichWithDictionaryStringObject()
28+
{
29+
const string propertyName = "Foo";
30+
const string expectedValue = "Bar";
31+
32+
var(loggerProvider, logEventPropertyFactory, logEvent) = SetUp();
33+
34+
35+
var state = new Dictionary<string, object?>() { { propertyName, expectedValue } };
36+
37+
var loggerScope = new SerilogLoggerScope(loggerProvider, state);
38+
39+
loggerScope.EnrichAndCreateScopeItem(logEvent, logEventPropertyFactory, out LogEventPropertyValue? scopeItem);
40+
41+
Assert.Contains(propertyName, logEvent.Properties);
42+
43+
var scalarValue = logEvent.Properties[propertyName] as ScalarValue;
44+
Assert.NotNull(scalarValue);
45+
46+
var actualValue = scalarValue.Value as string;
47+
Assert.NotNull(actualValue);
48+
Assert.Equal(expectedValue, actualValue);
49+
}
50+
51+
[Fact]
52+
public void EnrichWithIEnumerableKeyValuePairStringObject()
53+
{
54+
const string propertyName = "Foo";
55+
const string expectedValue = "Bar";
56+
57+
var (loggerProvider, logEventPropertyFactory, logEvent) = SetUp();
58+
59+
60+
var state = new KeyValuePair<string, object?>[] { new KeyValuePair<string, object?>(propertyName, expectedValue) };
61+
62+
var loggerScope = new SerilogLoggerScope(loggerProvider, state);
63+
64+
loggerScope.EnrichAndCreateScopeItem(logEvent, logEventPropertyFactory, out LogEventPropertyValue? scopeItem);
65+
66+
Assert.Contains(propertyName, logEvent.Properties);
67+
68+
var scalarValue = logEvent.Properties[propertyName] as ScalarValue;
69+
Assert.NotNull(scalarValue);
70+
71+
var actualValue = scalarValue.Value as string;
72+
Assert.NotNull(actualValue);
73+
Assert.Equal(expectedValue, actualValue);
74+
}
75+
76+
[Fact]
77+
public void EnrichWithTupleStringObject()
78+
{
79+
const string propertyName = "Foo";
80+
const string expectedValue = "Bar";
81+
82+
var (loggerProvider, logEventPropertyFactory, logEvent) = SetUp();
83+
84+
85+
var state = (propertyName, (object)expectedValue);
86+
87+
var loggerScope = new SerilogLoggerScope(loggerProvider, state);
88+
89+
loggerScope.EnrichAndCreateScopeItem(logEvent, logEventPropertyFactory, out LogEventPropertyValue? scopeItem);
90+
91+
Assert.Contains(propertyName, logEvent.Properties);
92+
93+
var scalarValue = logEvent.Properties[propertyName] as ScalarValue;
94+
Assert.NotNull(scalarValue);
95+
96+
var actualValue = scalarValue.Value as string;
97+
Assert.NotNull(actualValue);
98+
Assert.Equal(expectedValue, actualValue);
99+
}
100+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Serilog.Core;
5+
using Serilog.Events;
6+
7+
namespace Serilog.Extensions.Logging.Tests.Support;
8+
internal class LogEventPropertyFactory : ILogEventPropertyFactory
9+
{
10+
public LogEventProperty CreateProperty(string name, object? value, bool destructureObjects = false)
11+
{
12+
var scalarValue = new ScalarValue(value);
13+
return new LogEventProperty(name, scalarValue);
14+
}
15+
}

0 commit comments

Comments
 (0)