2013-10-14 1 views
7

Я регистрирую свои сообщения в поле базы данных с максимальным размером 1000 символов. В настоящее время, если я пытаюсь зарегистрировать сообщение (которое часто содержит информацию об исключении со стеком трассировки, содержимым запроса HTTP и т. Д.), Которое превышает 1000 символов, вставка терпит неудачу, и NLog (как следует) молча игнорирует это и продолжает двигаться.NLog auto truncate messages

Есть ли что-то, что я могу добавить в свой NLog.config, чтобы объявить, что длина сообщения всегда должна быть усечена, поэтому она не превышает 1000 символов?

Бонусные баллы, если вы можете сказать мне, как изящно отметить усеченные сообщения, заменив последние несколько символов до предела 1000 символов чем-то вроде «[... Усеченный]».

Не могу поверить, что я не могу с легкостью найти это с помощью некоторых поисковых запросов. Надеюсь, мне не нужно писать собственный рендер?

ответ

5

Я не знаю встроенный способ сделать это. Вместо этого я бы написал LayoutRenderer (на самом деле, WrapperLayoutRenderer). Это не сложно.

Что-то вроде этого (непроверенные) должна это сделать:

[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; 
    } 
} 
+1

Спасибо. Это, безусловно, выглядит легко, но я надеялся избежать этого, главным образом потому, что в конечном итоге получим этот досадный маленький класс, который должен был бы зависеть от всех моих проектов, которые используют эту систему ведения журналов, и похоже, что это не так. стоит обслуживания. –

2

В log4net я должен указать left (@msg, 1000) в инструкции insert, чтобы сообщение соответствовало столбцу базы данных. Вероятно, вы можете сделать что-то подобное в nlog.

В SQL Server можно построить вставку в .. выбрать из-заявления с использованием этого фрагмента:

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

Спасибо. Эта 'left (@msg, 1000)' вещь в log4net была бы идеальной:/Я в конечном итоге сделал то, что вы предложили, SQL-стороне, в хранимой процедуре, которая обертывает вставку. Хотел бы я отметить как принятый ответ, но, хотя я и делал то, что вы предлагали, я чувствую, что ответ wageoghe более полезен в общем случае. –

+0

Это на самом деле довольно хорошая идея, обертывание вставки в хранимой процедуре и выполнение усечения там! – wageoghe

+0

вы можете сделать 'left (@msg, 1000)' в NLog – Turch

2

Один из способов сделать это с помощью регулярной замены выражение сообщения, которое можно определить прямо в 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}"/>