Search code examples
c#.netasp.net-corenlogmicrosoft-extensions-logging

NLog EventProperties in .NET Core


I'm using ILogger<MyController> to write logs using DI (see step 6)

I'm also using NLog EventProperties

I want to add traceId to all my logs in my controller automatically.

This is working:

logger.Info("Some log. TraceId:{traceId}", 123);

However, then I need to change all my log commands (a lot of them!), which is a pain.

If I do the following, it's not tread safe:

using NLog;
public class MyController : Controller
{
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
    public MyConstructor(Apilog apilog)
    {
        Logger.SetProperty("traceid", apilog.TraceId);
    }
}

Is there some way to use SetProperty with ILogger<MyController>?

Or some way of using NLog with SetProperty in a fast and thread safe way?

Many thanks in advance!


Solution

  • When you share loggers between threads, then you could use WithProperty to ensure thread safeness.

    Please note that WithProperty/SetProperty is only available on the Logger of NLog. (so not ILogger of Microsoft.Extensions.Logging`). See below.

    Example:

    using NLog;
    public class MyController : Controller
    {
        private static readonly Logger BaseLogger = LogManager.GetCurrentClassLogger(); 
    
        private readonly Logger Logger; // non static because of traceid. 
        public MyConstructor(Apilog apilog)
        {        
            Logger = BaseLogger.WithProperty("traceid", apilog.TraceId);
        }
    }
    

    Is there some way to use SetProperty with ILogger<MyController>?

    There is no SetProperty on the ILogger interface of Microsoft.Extensions.Logging, but you could do this:

    using (_logger.BeginScope(new[] { new KeyValuePair<string, object>("traceid", apilog.TraceId) }))
    {
       _logger.LogDebug("Log message");
    }
    

    And use in your config: ${mdlc:traceid}. See more details and options here