سؤال

I'm logging my messages to a database field with a max size of 1000 characters. Currently if I try to log a message (which often contains exception information with stack trace, HTTP request content, etc.) that's larger than 1000 characters, the insert fails and NLog (as it should) silently ignores that and keeps going.

Is there something I can put in my NLog.config to declare that the message length should always be truncated so it's no greater than 1000 characters?

Bonus points if you can tell me how to gracefully mark truncated messages by replacing the last few characters before the 1000 character limit with something like "[...Truncated]".

Can't believe I can't readily find this with some googling. Hopefully I don't have to write my own renderer?

هل كانت مفيدة؟

المحلول 2

I don't know of a built in way to do it. Instead, I would write a LayoutRenderer (actually, a WrapperLayoutRenderer). It's not hard.

Something like this (untested) ought to do it:

[LayoutRenderer("truncate")]
[ThreadAgnostic]
public sealed class TruncateLayoutRendererWrapper : WrapperLayoutRendererBase
{
    public TruncateLayoutRendererWrapper()
    {
        this.Truncate = true;
        this.Ellipsis = true;
        this.Limit = 1000;
    }

    [DefaultValue(true)]
    public bool Truncate { get; set; }

    [DefaultValue(true)]
    public bool Ellipsis { get; set; }

    [DefaultValue(1000)]
    public bool Limit { get; set; }

    /// <summary>
    /// Post-processes the rendered message. 
    /// </summary>
    /// <param name="text">The text to be post-processed.</param>
    /// <returns>Trimmed string.</returns>
    protected override string Transform(string text)
    {
        if (!Truncate || Limit <= 0) return text;

        var truncated = text.Substring(0, Ellipsis ? Limit - 3 : Limit);
        if (Ellipsis) truncated += "...";

        return truncated;
    }
}

نصائح أخرى

NLog 4.6.3 supports this:

${message:truncate=1000}

Older versions of NLog can do this:

${trim-whitespace:inner=${message:padding=-1000:fixedLength=true}}

One way to do this is by using regular expression replacement of the message, which you can define right in the nlog.config. I used the following to truncate to 500 characters:

<variable name="truncated_message" value="${replace:replaceWith=...TRUNCATED:regex=true:inner=${message}:searchFor=(?&lt;\=.\{500\}).+}"/>

<target name="filelog" xsi:type="File" fileName="${basedir}/../logs/jobs/${shortdate}.log" layout="${date:format=yyyy-MM-dd HH\:mm\:ss.fff}|${level:uppercase=true}|${truncated_message}"/>

In log4net I'd specify left(@msg, 1000) in the insert statement to ensure the message fits the database column. You can probably do something similar in nlog.

In sql server you can construct an insert into .. select from-statement utilizing this fragment:

case when len(@msg) > 1000 then left(@msg, 988)+' [truncated]' else @msg end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top