代码之家  ›  专栏  ›  技术社区  ›  mo.

NLog自动截断消息

  •  10
  • mo.  · 技术社区  · 11 年前

    我正在将消息记录到一个最大大小为1000个字符的数据库字段中。目前,如果我试图记录一条超过1000个字符的消息(其中通常包含带有堆栈跟踪的异常信息、HTTP请求内容等),插入会失败,NLog(应该如此)会默默地忽略这一点并继续进行。

    有没有什么东西可以放在我的NLog.config中,声明消息长度应该总是被截断,这样它就不超过1000个字符?

    如果你能告诉我如何通过将1000个字符限制前的最后几个字符替换为类似的字符来优雅地标记被截断的消息,那将获得额外的积分 “[…截断]” .

    真不敢相信我在谷歌上找不到这个。希望我不必编写自己的渲染器?

    4 回复  |  直到 11 年前
        1
  •  9
  •   Rolf Kristensen Raúl Diego    6 年前

    NLog 4.6.3支持这一点:

    ${message:truncate=1000}
    

    旧版本的NLog可以做到这一点:

    ${trim-whitespace:inner=${message:padding=-1000:fixedLength=true}}
    
        2
  •  5
  •   wageoghe    11 年前

    我不知道有什么内置的方法可以做到这一点。相反,我会写一个LayoutRenderer(实际上是一个WrapperAlayoutRenderer)。这并不难。

    像这样的事情(未经测试)应该做到:

    [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;
        }
    }
    
        3
  •  5
  •   user1411430    10 年前

    实现这一点的一种方法是使用正则表达式替换消息,您可以在nlog.config中定义它。我使用以下内容将其截断为500个字符:

    <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
  •  4
  •   EventHorizon    11 年前

    在log4net中,我会在insert语句中指定left(@msg,1000),以确保消息适合数据库列。你可能可以在nlog中做类似的事情。

    在sql server中,您可以在..中构造一个插入。。从使用此片段的语句中选择:

    case when len(@msg) > 1000 then left(@msg, 988)+' [truncated]' else @msg end