Skip to content

Latest commit

 

History

History
90 lines (62 loc) · 2.83 KB

How-to-write-a-custom-layout-renderer.md

File metadata and controls

90 lines (62 loc) · 2.83 KB

Since NLog 4.4 there are two ways to create a custom layout renderer.

You could write a custom layout with one lambda function - it will be registered intermediately, or you could write a class which is easier to share across projects.

Lambda Function

Introduced in NLog 4.4

For simple cases, you could create a layout renderer with a lambda.

The lambda function will accept 1 or 2 parameters and should return a string.

  • 1 parameter: the logEventInfo.
  • 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.Message.Length);

//Using config, ${targetCount}
LayoutRenderer.Register("targetCount",(logEvent, config) => config.AllTargets.Count);

Class

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

Don't forget to [[register your custom component|Register-your-custom-component]]!

Example

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

[LayoutRenderer("hello-world")]
public class HelloWorldLayoutRenderer : LayoutRenderer
{
    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
        builder.Append("hello world!");
    }
}

How to pass configuration options to the layout render?

Just create public properties on the Layout Renderer. The properties could be decorated with the [RequiredParameter] and [DefaultParameter] attributes. The [DefaultParameter] can be passed to the layout renderer without using the name.

for example:

[LayoutRenderer("hello-world")]
public class HelloWorldLayoutRenderer : LayoutRenderer
{
        /// <summary>
        /// I'm not required or default
        /// </summary>
        public string Config1 { get; set; }

        /// <summary>
        /// I'm required
        /// </summary>
        [RequiredParameter]
        public string Config2 { get; set; }

        /// <summary>
        /// I'm the default parameter. You can set me as required also.
        /// </summary>
        [DefaultParameter]
        public bool Caps {get;set;}

Example usages

  • ${hello-world} - raises exception: required parameter Config2 isn't set
  • ${hello-world:Config2=abc} - OK, Config2 property set
  • ${hello-world:true:config2=abc} - default parameter (Caps) set to true
  • ${hello-world:true:config2=abc:config1=yes} - all the three properties set