9

I'm using NLog.Extensions.Logging.

When registering a logger factory using the method AddNLog(), it is possible to enable logging scope using NLogProviderOptions.IncludeScopes.

But how to make NLog write logging scope to a file?

I haven't found anything similar in the list of available layouts

Julian
  • 33,915
  • 22
  • 119
  • 174
Sergun
  • 93
  • 1
  • 5
  • Does this post help: https://learn.microsoft.com/en-gb/aspnet/core/fundamentals/logging/?tabs=aspnetcore2x&view=aspnetcore-3.1#log-scopes? – Mike Parkhill Feb 20 '20 at 18:06
  • @MikeParkhill unlikely, he asking how to write which scope is being used in the log, not how to use scoped logging – TheBatman Feb 20 '20 at 18:09
  • yeah, that post calls out that it will be included in the log if configured properly - thought it might help them see what they're missing – Mike Parkhill Feb 20 '20 at 18:18
  • If you just want to add an additional logevent property, then this might be of interest: https://github.com/NLog/NLog.Extensions.Logging/wiki/NLog-properties-with-Microsoft-Extension-Logging – Rolf Kristensen Feb 22 '20 at 07:32

2 Answers2

20

An example:

Log like this:

// logger is here of type Microsoft.Extensions.Logging.ILogger
using (logger.BeginScope(new[] { new KeyValuePair<string, object>("userid", request.UserId) }))
{
   logger.LogDebug("My log message");
}

Render like this: ${mdlc:userid}.

For example in the file target:

 <target name="file" xsi:type="File"
     layout="${longdate} ${logger} ${message}${exception:format=ToString}, user: ${mdlc:userid}" 
     fileName="${basedir}/${shortdate}.log" />

Note: NLogProviderOptions.IncludeScopes is enabled by default.

NLog directly

The syntax is a bit clumsy, but that is because Microsoft's abstraction is a bit limited. See also this issue: .NET - Logging structured data without it appearing in the text message

If you refer NLog directly, you could also do:

using (NLog.MappedDiagnosticsLogicalContext.SetScoped("userid", request.UserId))
{
   // logger here of type NLog.Logger
   logger.Info("My log message");
}

Also this is rendered with ${mdlc:userid}

More examples and different scopes for NLog explained here

Docs

PS: I have updated available layouts, so you could find it easier :)

enter image description here

Julian
  • 33,915
  • 22
  • 119
  • 174
  • 3
    It isn't necessary to pass the KeyValuePair array when creating a scope. I'm using template string with params, and it works well. Like this: `logger.BeginScope("{userid}", request.UserId)` – Vladimir Shiyanov May 19 '20 at 17:06
  • Answer and docs uses different syntax. So its ${mdlc:userid} or ${mdlc:item=userid}? – dimaaan Apr 23 '21 at 15:15
  • 1
    Both are fine. `item` is the default for this renderer, so you could skip it – Julian Apr 24 '21 at 10:24
1

New (in V5) is to use ${scopenested}.

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

Daniel Lidström
  • 9,930
  • 1
  • 27
  • 35