Skip to content

Commit

Permalink
BeginScope can also be called with string-format (FormattedLogValues)
Browse files Browse the repository at this point in the history
  • Loading branch information
snakefoot committed Jul 26, 2018
1 parent 4211602 commit 9e8395d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 14 deletions.
5 changes: 4 additions & 1 deletion src/NLog.Extensions.Logging/Logging/NLogBeginScopeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static IDisposable CreateDiagnosticLogicalContext<T>(T state)
if (state?.GetType().IsSerializable ?? true)
return NestedDiagnosticsLogicalContext.Push(state);
else
return NestedDiagnosticsLogicalContext.Push(state.ToString()); // Support ViewComponentLogScope, ActionLogScope and others
return NestedDiagnosticsLogicalContext.Push(state.ToString()); // Support HostingLogScope, ActionLogScope, FormattedLogValues and others
#endif
}
catch (Exception ex)
Expand All @@ -80,6 +80,9 @@ public static ScopeProperties CreateFromState(IReadOnlyList<KeyValuePair<string,
for (int i = 0; i < messageProperties.Count; ++i)
{
var property = messageProperties[i];
if (i == messageProperties.Count - 1 && i > 0 && property.Key == NLogLogger.OriginalFormatPropertyName)
continue; // Handle BeginScope("Hello {World}", "Earth")

scope.AddProperty(property.Key, property.Value);
}

Expand Down
45 changes: 32 additions & 13 deletions test/CustomBeginScopeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Xunit;

Expand All @@ -14,22 +13,33 @@ public class CustomBeginScopeTest : NLogTestBase
public void TestNonSerializableSayHello()
{
var runner = GetRunner<CustomBeginScopeTestRunner>();
var target = new NLog.Targets.MemoryTarget() { Layout = "${message} ${ndlc}" };
var target = new NLog.Targets.MemoryTarget() { Layout = "${message} ${mdlc:World} ${ndlc}" };
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target);
runner.SayHello().Wait();
Assert.Single(target.Logs);
Assert.Contains("Hello World", target.Logs[0]);
Assert.Contains("Hello Earth Earth", target.Logs[0]);
}

[Fact]
public void TestNonSerializableSayNothing()
{
var runner = GetRunner<CustomBeginScopeTestRunner>(new NLogProviderOptions() { IncludeScopes = false });
var target = new NLog.Targets.MemoryTarget() { Layout = "${message} ${ndlc}" };
var target = new NLog.Targets.MemoryTarget() { Layout = "${message} ${mdlc:World} ${ndlc}" };
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target);
runner.SayHello().Wait();
Assert.Single(target.Logs);
Assert.Contains("Hello ", target.Logs[0]);
Assert.Contains("Hello ", target.Logs[0]);
}

[Fact]
public void TestNonSerializableSayHi()
{
var runner = GetRunner<CustomBeginScopeTestRunner>();
var target = new NLog.Targets.MemoryTarget() { Layout = "${message} ${mdlc:World} ${ndlc}" };
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target);
runner.SayHi().Wait();
Assert.Single(target.Logs);
Assert.Contains("Hi Earth Earth", target.Logs[0]);
}

public class CustomBeginScopeTestRunner
Expand All @@ -43,26 +53,35 @@ public CustomBeginScopeTestRunner(ILogger<CustomBeginScopeTestRunner> logger)

public async Task SayHello()
{
using (_logger.BeginScope(new ActionLogScope("World")))
using (_logger.BeginScope(new ActionLogScope("Earth")))
{
await Task.Yield();
_logger.LogInformation("Hello");
}
}

public async Task SayHi()
{
using (_logger.BeginScope("{World}", "Earth"))
{
await Task.Yield();
_logger.LogInformation("Hi");
}
}
}

private class ActionLogScope : IReadOnlyList<KeyValuePair<string, object>>
{
private readonly string _action;
private readonly string _world;

public ActionLogScope(string action)
public ActionLogScope(string world)
{
if (action == null)
if (world == null)
{
throw new ArgumentNullException(nameof(action));
throw new ArgumentNullException(nameof(world));
}

_action = action;
_world = world;
}

public KeyValuePair<string, object> this[int index]
Expand All @@ -71,7 +90,7 @@ public ActionLogScope(string action)
{
if (index == 0)
{
return new KeyValuePair<string, object>("ActionId", _action);
return new KeyValuePair<string, object>("World", _world);
}
throw new IndexOutOfRangeException(nameof(index));
}
Expand All @@ -91,7 +110,7 @@ public override string ToString()
{
// We don't include the _action.Id here because it's just an opaque guid, and if
// you have text logging, you can already use the requestId for correlation.
return _action;
return _world;
}

IEnumerator IEnumerable.GetEnumerator()
Expand Down

0 comments on commit 9e8395d

Please sign in to comment.