0
votes

I have a custom made NLog AsyncTaskTarget target. At a first glance it seems to be working fine. I can log all messages within my custom Target class.

But, I would like to have structured logging. So I have setup my nlog.config like this within my <target>:

<layout xsi:type="JsonLayout">
  <attribute name="time" layout="${longdate}" />
  <attribute name="level" layout="${level:upperCase=true}"/>
  <attribute name="message" layout="${message}" />
  <attribute name="Properties" encode="false" >
    <layout type='JsonLayout' includeAllProperties="true" excludeProperties="EventId_Id,EventId_Name,EventId" maxRecursionLimit="5"/>
  </attribute>
</layout>

Is there a way to also get the properties that are specified in the attribute tags within the log method?

For some reason the property values are alway null or empty.

protected override async Task WriteAsyncTask(IList<LogEventInfo> logEvents, CancellationToken cancellationToken)
{
    foreach (var info in logEvents)
    {
        string logMessage = RenderLogEvent(Layout, info); // renders message
        var props = GetAllProperties(info); // count = 0
        var p = GetContextProperties(info); // = null
    }
}
1
Please share the logger call. - Julian
@Julian Do you mean this: _logger.LogInformation($"Test info: {DateTime.Now}");? This is inside a Controller class. - Vivendi

1 Answers

1
votes

You are mixing two features together. You have registered JsonLayout as target-Layout, so it will generate a Json-document for each LogEvent.

protected override async Task WriteAsyncTask(IList<LogEventInfo> logEvents, CancellationToken cancellationToken)
{
    foreach (var info in logEvents)
    {
        string jsonDocument = RenderLogEvent(Layout, info); // Renders using JsonLayout
        var props = GetAllProperties(info);               // Renders properties
    }
}

You can configure your target to return properties when calling GetAllProperties(), but you have to enable it first like this:

<target type="MyFirst" name="first" includeEventProperties="true" includeMdlc="true">
  <contextproperty name="MachineName" layout="${machinename}" />
  <contextproperty name="ThreadId" layout="${threadid}" />
</target>

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