NLog auto truncate messages

末鹿安然 提交于 2020-12-08 05:50:16

问题


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?


回答1:


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;
    }
}



回答2:


NLog 4.6.3 supports this:

${message:truncate=1000}

Older versions of NLog can do this:

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



回答3:


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}"/>



回答4:


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


来源:https://stackoverflow.com/questions/19368284/nlog-auto-truncate-messages

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!