NLog formatting as JSON using BeginScope

662 Views Asked by At

How do you get NLog to format data as JSON when using ILogger.BeginScope? It appears the the @ symbol is ignored, or just not coded to work with begin scope? ref documentation

I've tried every combination I can think of and they all result in the object being ToString'd rather than converted to JSON. The end result is that the data is not searchable as "structured" data because it's just a string.

1st Attempt:

using (_logger.BeginScope(new Dictionary<string, object>
{
    ["CacheValue"] = value
}))
{
    _logger.LogInfo("howdy");
}

Result in Seq:

howdy
CacheValue MyApp.ViewModels.EntityIssueQueueGetModel

2nd Attempt:

using (_logger.BeginScope(new Dictionary<string, object>
{
    ["@CacheValue"] = value
}))
{
    _logger.LogInfo("howdy");
}

Result in Seq:

howdy
@CacheValue MyApp.ViewModels.EntityIssueQueueGetModel

3rd Attempt:

using (_logger.BeginScope(new Dictionary<string, object>
{
    ["{@CacheValue}"] = value
}))
{
    _logger.LogInfo("howdy");
}

Result in Seq:

howdy
{@CacheValue} MyApp.ViewModels.EntityIssueQueueGetModel

4th Attempt:

using (_logger.BeginScope("{@CacheValue}", value))
{
    _logger.LogInfo("howdy");
}

Result in Seq:

howdy
@CacheValue MyApp.ViewModels.EntityIssueQueueGetModel

This next bit works, but is not what I need. This prints the JSON out along with the friendly message. I only want the JSON data to be associated with the log for querying purposes; not shown as part of the message.

Working example:

_logger.LogInfo("howdy. {@CacheValue}", value);

Result in Seq:

howdy. {"Issues":[],"TotalRecords":0,"Success":true,"TraceId":"00-3b8ef0c2d84714e0c81a07cbb5d50444-8269922e21923478-00","Errors":[]}
CacheValue {
  "Issues": [],
  "TotalRecords": 0,
  "Success": true,
  "TraceId": "00-3b8ef0c2d84714e0c81a07cbb5d50444-8269922e21923478-00",
  "Errors": []
}
1

There are 1 best solutions below

0
On

NLog doesn't recognize message-template-syntax for Scope-Context-Properties.

NLog JsonLayout can format Scope-context Properties like this:

  <layout xsi:type="JsonLayout" includeScopeProperties="true" maxRecursionLimit="1">
  </layout>

See also: https://github.com/NLog/NLog/wiki/JsonLayout

It is also possible to format a single Scope-context Property as Json like this:

  layout="${scopeproperty:CacheValue:format=@}"

See also: https://github.com/NLog/NLog/wiki/ScopeProperty-Layout-Renderer

It is also possible to format the entire Scope-Nested-Stack as Json like this:

  layout="${scopenested:format=@}"

See also: https://github.com/NLog/NLog/wiki/ScopeNested-Layout-Renderer

Maybe consider posting your question at https://github.com/datalust/nlog-targets-seq