Reputation: 4537
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
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