Skip to content
Rolf Kristensen edited this page Nov 8, 2023 · 35 revisions

Besides the information included with the log message, then there are several options for capturing additional local context state with the LogEvent:

  • ${logger} - Name of the Logger-object used for writing LogEvent.
  • ${level} - LogEvent Level of importance / severity.
  • ${exception} - Exception object included with the LogEvent.
  • ${event-properties} - LogEvent Properties - From Structured logging or explicity added to LogEventInfo.Properties.
  • ${gdc} - Global Diagnostic Context for application-wide static context assigned at startup.
  • ${activityid} - System.Diagnostics.Trace.CorrelationManager.ActivityId allows you to assign and capture correlation-id / request-id. Alternative one can use ${aspnet-TraceIdentifier}
  • ${scopeproperty} - Provide context properties for the current thread with async Task-support

    Replaces the legacy ${mdlc} and ${mdc} from before NLog 5.0

  • ${scopenested} - Provide nested scope details for the current thread with async Task-support

    Replaces the legacy ${ndlc} and ${ndc} from before NLog 5.0

  • ${activity:TraceId} - Using System.Diagnostics.Activity.Current for OpenTelemetry spans.
  • ${aspnet-item} - ASP.NET Item variable from HttpContext.Items dictionary.

More LayoutRenderers

LogEvent Properties

See Structured logging for more details of using the log-message to inject additional properties:

logger.Info("Say hello to {myProperty}", "myValue");

One can also use the Fluent-Logger-API:

logger.ForInfoEvent().Message("Hello").Property("myProperty", "myValue").Log();

Or explicitly create the LogEvent:

var logEvent = LogEventInfo() { Level = LogLevel.Info };
logEvent.Properties["myProperty"] = "myValue";
logger.Log(logEvent);

It is also possible to inject properties into the Logger-object, so they are always added:

logger.WithProperty("myProperty", "myValue").Info("Hello"); // NLog 4.6.3+

LogEvent Properties can be rendered with ${event-properties:item=myProperty}, ${all-event-properties} or JsonLayout.

ScopeContext Properties

Handles thread context properties for a scope. Ex. assigning RequestId for the method-call-scope:

using (NLog.ScopeContext.PushProperty("myRequestId", Guid.NewGuid()))
{
   logger.Info("myLogEvent");
}

Thread Context Properties can be rendered with ${scopeproperty:item=myRequestId} or JsonLayout with IncludeScopeProperties=true.

Note when using Microsoft Extension Logging ILogger.BeginScope with NLog.Extension.Logging, then it will automatically update NLog ScopeContext with provided properties.

ScopeContext Nested States

Handles thread context naming of a scope. Ex. assigning MethodName for the method-call-scope:

using (NLog.ScopeContext.PushNestedState("myMethodName"))
{
   logger.Info("myLogEvent");
}

Thread Scope names can be rendered with ${scopenested}.

Note when using Microsoft Extension Logging ILogger.BeginScope with NLog.Extension.Logging, then it will automatically update NLog ScopeContext with provided scope-name.

.NET Core logging

When using NLog.Extensions.Logging or NLog.Web.AspNetCore, you can also use BeginScope and more advanced options:

//note: render userId via ${scopeproperty:userid}
using (_logger.BeginScope(new[] { new KeyValuePair<string, object>("userid", request.UserId) }))
{
   _logger.LogDebug("Start process {OperationName}", "Main");
}

Context for Code or HttpContext

Need other context from code or from the HttpContext (ASP.NET or ASP.NET Core). You could write a custom layout renderer with a single line, see How to write a custom layout renderer.

Clone this wiki locally