eiu165
eiu165

Reputation: 6261

nlog substring in layout

is there a way to get a substring of the message to the nlog layout? something like ${${substring(0,200)}message}

        <parameter name="@Summary" layout="${substring(0,200)}${message}"/>

It would be cool if that would write the equlivent of message.substring(0, 200);

    <target type="Database" name="databaseLog" 
             ConnectionStringName="ApplicationConnectionString">
        <commandText>
            INSERT INTO [Log] ([Description] ,[Summary] ,[Level] )
            VALUES            (@Description,  @Summary,  @Level  )
        </commandText>

        <parameter name="@Description" layout="${message}"/>
        <parameter name="@Summary" layout="{{SUBSTRING-OF-MESSAGE-HERE}}"/>
        <parameter name="@Level" layout="${level}"/> 
    </target> 

Upvotes: 4

Views: 3308

Answers (3)

Rolf Kristensen
Rolf Kristensen

Reputation: 19867

NLog 4.6.3 can now perform substring-logic:

https://github.com/NLog/NLog/wiki/Substring-layout-renderer

And truncate:

${mesage:truncate=80}

Upvotes: 2

NorwegianBlue
NorwegianBlue

Reputation: 11

Try this. I had the same problem and ended up writing this.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Your.NameSpace
{
    [NLog.LayoutRenderers.LayoutRenderer("shorten")]
    [NLog.LayoutRenderers.AmbientProperty("HeadLength")]
    [NLog.LayoutRenderers.AmbientProperty("TailLength")]
    [NLog.LayoutRenderers.AmbientProperty("WarnMsg")]
    public class ShortenRendererWrapper : NLog.LayoutRenderers.Wrappers.WrapperLayoutRendererBase
    {


        [System.ComponentModel.DefaultValue(500)]
        public int HeadLength { get; set; }

        [System.ComponentModel.DefaultValue(500)]
        public int TailLength { get; set; }

        [System.ComponentModel.DefaultValue(true)]
        public bool ShowWarnMsg { get; set; }

        [System.ComponentModel.DefaultValue("###_SHORTENED_###")]
        public string WarnMsg { get; set; }

        public ShortenRendererWrapper()
        {
            HeadLength = 500;
            TailLength = 500;
            ShowWarnMsg = true;
            WarnMsg = "###_SHORTENED_###";
        }

        protected override string Transform(string text)
        {
            if (text.Length > (HeadLength + TailLength))
            {
                if (HeadLength > 0 && TailLength > 0)
                    return text.Substring(0, HeadLength)
                        + (ShowWarnMsg ? "<........." + WarnMsg + ".........>" : string.Empty)
                        + text.Substring(text.Length - TailLength, TailLength);
                else if (HeadLength > 0)
                    return text.Substring(0, HeadLength)
                        + (ShowWarnMsg ? "<........." + WarnMsg + ">" : string.Empty);
                else if (TailLength > 0)
                    return (ShowWarnMsg ? "<" + WarnMsg + ".........>" : string.Empty)
                        + text.Substring(text.Length - TailLength, TailLength);
                else
                    return text;
            }
            else
                return text;
        }        
    }
}

It is a wrapper renderer. Use by adding a 'extensions' tag to your nlog config file like

<nlog>
    <extensions>
        <add assembly="Your.Namespace"/>
    </extensions>
    <targets>
        <target layout="${shorten:headLength=1000:tailLength=200:inner=${message})"/>
    </targets>
</nlog>

This will give you 1000 chars from the beginning and 200 chars from the end of the log message with a warning in the middle that notifies the string is not complete. You can tailor the warning message by setting the 'warnMsg' value or turn it completely off by setting 'showWarnMsg' to 'false'. 'headLength' and 'tailLength' can be used alone to give a substring from the begining or the end of the string. If neither value is given or if the string is shorter than the sum of the value(s) specified, the string will be returned as is.

Upvotes: 1

kolbasov
kolbasov

Reputation: 1588

You may use ${pad} layout renderer:

layout=${pad:padding=-200:fixedLength=true:inner=${message}}

Positive padding values cause left padding, negative values cause right padding to the desired width. Documentation

Or try to use T-SQL SUBSTR:

<commandText>
  INSERT INTO [Log] ([Description] ,[Summary] ,[Level] )
  VALUES (@Description,  SUBSTR(@Summary, 1, 200),  @Level)
</commandText>

Upvotes: 5

Related Questions