Skip to content

Commit

Permalink
NLogBeginScopeParser - Skip capture of nested state when List + Array…
Browse files Browse the repository at this point in the history
… + Dictionary (#662)
  • Loading branch information
snakefoot authored Mar 28, 2023
1 parent 8ef4b2d commit 3e59cae
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
15 changes: 14 additions & 1 deletion src/NLog.Extensions.Logging/Logging/NLogBeginScopeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,20 @@ public IDisposable ParseBeginScope<T>(T state)
{
if (state is IReadOnlyList<KeyValuePair<string, object>> scopePropertyList)
{
if (scopePropertyList is IList)
return ScopeContext.PushNestedStateProperties(null, scopePropertyList); // Probably List/Array without nested state

object scopeObject = scopePropertyList;
scopePropertyList = ParseScopeProperties(scopePropertyList);
return ScopeContext.PushNestedStateProperties(scopeObject, scopePropertyList);
}
else if (state is IReadOnlyCollection<KeyValuePair<string, object>> scopeProperties)
{
if (scopeProperties is IDictionary)
return ScopeContext.PushNestedStateProperties(null, scopeProperties); // Probably Dictionary without nested state
else
return ScopeContext.PushNestedStateProperties(scopeProperties, scopeProperties);
}

if (!(state is string))
{
Expand Down Expand Up @@ -181,7 +191,10 @@ public static IDisposable CaptureScopeProperties(IEnumerable scopePropertyCollec
propertyList.Add(propertyValue.Value);
}

return ScopeContext.PushNestedStateProperties(scopePropertyCollection, propertyList);
if (scopePropertyCollection is IList || scopePropertyCollection is IDictionary)
return ScopeContext.PushNestedStateProperties(null, propertyList); // Probably List/Array/Dictionary without nested state
else
return ScopeContext.PushNestedStateProperties(scopePropertyCollection, propertyList);
}

public static IDisposable CaptureScopeProperty<TState>(TState scopeProperty, ExtractorDictionary stateExtractor)
Expand Down
23 changes: 23 additions & 0 deletions test/NLog.Extensions.Logging.Tests/CustomBeginScopeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ public void TestNonSerializableSayNothing()
Assert.Equal("Nothing", target.Logs[0]);
}

[Fact]
public void TestNonSerializableSaySomething()
{
var runner = GetRunner<CustomBeginScopeTestRunner>();
var target = new Targets.MemoryTarget { Layout = "${message}${scopeproperty:Say}" };
ConfigureNLog(target);
runner.SaySomething().Wait();
Assert.Single(target.Logs);
Assert.Equal("SaySomething", target.Logs[0]);
}

public class CustomBeginScopeTestRunner
{
private readonly ILogger<CustomBeginScopeTestRunner> _logger;
Expand Down Expand Up @@ -111,6 +122,18 @@ public async Task SayNothing()
_logger.LogInformation("Nothing");
}
}

public async Task SaySomething()
{
using (var scopeState = _logger.BeginScope(new Dictionary<string, object>()
{
{ "Say", "Something" },
}))
{
await Task.Yield();
_logger.LogInformation("Say");
}
}
}

private class ActionLogScope : IReadOnlyList<KeyValuePair<string, object>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void AddNLog_LoggerFactory_IncludeActivityIdsWithBeginScope()
var logger = loggerFactory.CreateLogger(nameof(AddNLog_LoggerFactory_IncludeActivityIdsWithBeginScope));
var activity = new System.Diagnostics.Activity("TestActivity").SetParentId("42").Start();
var scopeProperties = new Dictionary<string, object> { { "RequestId", "123" }, { "RequestPath", "Unknown" } };
using (logger.BeginScope(scopeProperties.ToList()))
using (logger.BeginScope(new ArraySegment<KeyValuePair<string, object>>(scopeProperties.ToArray())))
{
logger.LogInformation(default(EventId), "test message with {0} arg", 1);
}
Expand Down

0 comments on commit 3e59cae

Please sign in to comment.