Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/NLogPublic

How to write a custom layout renderer

Rolf Kristensen edited this pageMay 11, 2025 ·45 revisions

Layout renderers can capture, format and output additional context details that can be used byNLog Layouts. There are 2 ways to create a custom layout renderer.

  1. Register custom lambda-delegate-function with a symbol-name (Introduced with NLog v4.4)
  2. Register custom class that inherits fromLayoutRenderer that also supports additional configuration options.

⚠️ Don't forget toregister your custom component when loading NLog config!

Lambda Function

NLog 4.7 introduces a fluent registration API usingLogManager.Setup(), where you create a layout renderer with a lambda:

NLog.LogManager.Setup().SetupExtensions(s=>s.RegisterLayoutRenderer("trace_id",(logevent)=>CorrelationIdentifier.TraceId.ToString()));

NLog 4.4 was the first edition to support lambda function will accept 1 or 2 parameters and should return astring.

  • 1 parameter: thelogEventInfo.
  • 2 parameters:logEventInfo and the current NLog config.

Examples

//register ${text-fixed}LayoutRenderer.Register("text-fixed",(logEvent)=>"2");//register ${trace-identifier}LayoutRenderer.Register("trace-identifier",(logEvent)=>HttpContext.Current.TraceIdentifier);//Using logEventInfo, ${message-length}LayoutRenderer.Register("message-length",(logEvent)=>logEvent.FormattedMessage.Length);//Using config, ${targetCount}LayoutRenderer.Register("targetCount",(logEvent,config)=>config.AllTargets.Count);

ASP.NET HttpContext

Need the HTTP-context (e.g. Request, Session etc) for ASP.NET or ASP.NET Core?

Include theNLog.Web (ASP.NET Classic) orNLog.Web.AspNetCore nuget-package.

And usage:

usingNLog.Web.LayoutRenderers;AspNetLayoutRendererBase.Register("SessionItem1",(logEventInfo,httpContext,loggingConfiguration)=>httpContext.Session["SessionItem"]);// usage ${SessionItem1}

Class

Create a class that inherits fromNLog.LayoutRenderers.LayoutRenderer, set the[LayoutRenderer("your-name")] on the class and override theAppend(StringBuilder builder, LogEventInfo logEvent) method.Invoke in this methodbuilder.Append(..) to render your custom layout renderer.

Example

We create a${hello-world} layout renderer, which renders..."hello world!".

[LayoutRenderer("hello-world")]publicclassHelloWorldLayoutRenderer:LayoutRenderer{protectedoverridevoidAppend(StringBuilderbuilder,LogEventInfologEvent){builder.Append("hello world!");}}

How to pass configuration options to the layout render?

Use public class-properties for configuring the LayoutRenderer:

[LayoutRenderer("hello-world")]publicclassHelloWorldLayoutRenderer:LayoutRenderer{/// <summary>/// New special option/// </summary>[DefaultParameter]publicstringSpecialOption{get;set;}/// <summary>/// New extra option/// </summary>publicboolExtraOption{get;set;}

The[DefaultParameter]-attribute can only be assigned to one class-property, and gives the ability to assign the class-property-value without specifying the class-property-name.

Example usages:

  • ${hello-world:Bonus} - AssignsSpecialOption =Bonus.
  • ${hello-world:SpecialOption=Bonus} - AssignsSpecialOption =Bonus.
  • ${hello-world:ExtraOption=true} - AssignsExtraOption =true.
  • ${hello-world:Bonus:ExtraOption=true} - AssignsSpecialOption =Bonus andExtraOption =true.

If additional option-validation are required, thenoverride void InitializeLayoutRenderer() and implement the necessary validation, andthrow NLogConfigurationException("...") when issues are detected.

How to optimize performance for the layout renderer

NLog will automatically capture relevant context state, when usingAsyncWrapper-target to perform actual writing on background-thread (to avoid logging objects after they have been disposed). The following class-attributes can used for the LayoutRenderer that enables additional performance:

  • [ThreadAgnostic]

    LayoutRenderer does not capture state from the application-thread logging. Ex.${threadid} cannot be[ThreadAgnostic].

    For LayoutRenderer marked as[ThreadAgnostic] then NLog can skip the overhead of capturing state.

    If just a single LayoutRenderer in a Layout is not marked as[ThreadAgnostic], then NLog introduces the overhead of state capture.

  • [ThreadSafe]

    Introduced with NLog 4.5.3, and made obsolete with NLog 5.0 that expects all to be threadsafe.

    LayoutRenderer will render correct output regardless of the number of application-threads running inside.

    For LayoutRenderer marked as[ThreadSafe] then NLog will skip using "global" locks when capturing state, thus application-threads willnot experience lock-congestion inside NLog.

    If just a single LayoutRenderer in a Layout is not marked as[ThreadSafe], then NLog introduces the overhead of "global" lock when doing state capture.

Example of class-attributes for LayoutRenderer:

usingNLog.Config;[LayoutRenderer("hello-world")][ThreadAgnostic]publicclassHelloWorldLayoutRenderer:LayoutRenderer{protectedoverridevoidAppend(StringBuilderbuilder,LogEventInfologEvent){builder.Append("hello world!");}}

Multiple type-alias attributes

NLog 5.0 enables you to have multiple type-aliases for a single class. Before one had to inherit from the same class to provide additional type-names.

[LayoutRenderer("hello-world")]// ${hello-world}[LayoutRenderer("hello-earth")]// ${hello-earth}publicclassHelloWorldLayoutRenderer:LayoutRenderer{

The type-alias can then be used when wanting to use the LayoutRenderer in NLog SimpleLayout.

Notice NLog 5.0 automatically ignores dashes- in type-alias, so no extra alias is needed for this: Ex.${helloworld}

-Troubleshooting Guide - See available NLog Targets and Layouts:https://nlog-project.org/config

Configuration

Programmatic Configuration

Advanced

Extending NLog

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp