Alexander
Alexander

Reputation: 4537

Merge property values with NLog

I usually use structured logging with NLog for my projects. If I use the same name of context, scoped and inline properties, it creates different properties by adding numeric suffix.

For example, consider the following snippet:

public void DoWithScope(string value)
{
    using var scoped = 
    _logger.BeginScope(new Dictionary<string, object>()
    {
        ["myProperty"] = value
    });
    MyMethod(value);
}

public void DoWithotScope(string value)
{
    MyMethod(value);
}

private void MyMethod(string value)
{
    try
    {
        // do something
        throw new Exception("Oops!");
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "The value \"{myProperty}\" causes an exception.", value);
    }
}

DoWithScope method creates myProperty and myProprty_1.

Of course, it's possible to disable nested scope in target settings, but sometimes it's important to use scoped and inline properties at the same time, because we don't know whether the scope already contains myProperty or nor, but we want to be sure the property is added. Also we can mix target with support of structured logging and without one.

So, in my opinion target context properties should be overwritten by properties from scope, scoped properties should be overwritten by inline properties. Is where way to implement such behavior by changing logging configuration?

Upvotes: 0

Views: 54

Answers (1)

Rolf Kristensen
Rolf Kristensen

Reputation: 19877

It is possible to perform explicit merging for specific properties:

<target type="MyTarget" excludeProperties="RequestId">
     <contextproperty name="RequestId" layout="${event-properties:RequestId:whenEmpty=${scope-property=RequestId:whenEmpty=DefaultValue}}" />
</sometarget>

Instead of DefaultValue then you could also use one of the NLog LayoutRenderers available. Ex. ${aspnet-TraceIdentifier} or ${activity:property=TraceId}. Or alternative skip whenEmpty=DefaultValue and rely on IncludeEmptyValue="false" (default).

See also: https://github.com/NLog/NLog/wiki/How-to-write-a-custom-target-for-structured-logging

Upvotes: 0

Related Questions