2013-10-14 7 views
7

Ich protokolliere meine Nachrichten in einem Datenbankfeld mit einer maximalen Größe von 1000 Zeichen. Wenn ich derzeit versuche, eine Nachricht zu protokollieren (die oft Ausnahmeinformationen mit Stack-Trace, HTTP-Anforderungsinhalt usw. enthält), die größer als 1000 Zeichen ist, schlägt die Einfügung fehl, und NLog (wie es sollte) ignoriert dies still und macht weiter.NLog automatische Abschneiden Nachrichten

Gibt es etwas, das ich in meine NLog.config legen kann, um zu deklarieren, dass die Nachrichtenlänge immer abgeschnitten werden sollte, so dass es nicht größer als 1000 Zeichen ist?

Bonuspunkte, wenn Sie mir sagen, wie anmutig abgeschnittene Nachrichten markieren, um durch die letzten Zeichen vor den 1000 Zeichen mit so etwas wie ersetzen „[... Verkürzte]“.

Ich kann nicht glauben, ich kann das nicht leicht mit etwas googeln finden. Hoffentlich muss ich meinen eigenen Renderer nicht schreiben?

Antwort

5

Ich weiß nicht, von einem in Art und Weise gebaut, es zu tun. Stattdessen würde ich einen LayoutRenderer (eigentlich einen WrapperLayoutRenderer) schreiben. Es ist nicht schwer.

Etwas Ähnliches (nicht getestet) sollte es tun:

[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

Danke. Es sieht sicherlich einfach aus, aber ich hatte gehofft, es zu vermeiden, hauptsächlich weil ich mit dieser nervigen kleinen Klasse enden würde, von der alle meine Projekte, die dieses Protokollierungssystem verwenden, abhängig sein müssten, und es scheint nicht so zu sein die Wartung wert. –

2

In log4net würde ich links (@msg, 1000) in der INSERT-Anweisung angeben, um sicherzustellen, dass die Nachricht die Datenbankspalte passt. Sie können wahrscheinlich etwas ähnliches in nlog tun.

in SQL Server können Sie einen Einsatz in .. wählen Sie aus-Anweisung Verwendung dieses Fragment konstruieren:

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

Danke. Das 'left (@msg, 1000)' Ding in log4net wäre perfekt:/Am Ende habe ich ziemlich genau das gemacht, was Sie vorgeschlagen haben, SQL-Seite, in einer gespeicherten Prozedur, die die Einfügung umschließt. Ich wünschte, ich könnte beides als die akzeptierte Antwort markieren, aber obwohl ich letztendlich das getan habe, was Sie vorgeschlagen haben, bin ich der Meinung, dass die Antwort von lowoghe im allgemeinen Fall nützlicher ist. –

+0

Das ist eigentlich eine ziemlich gute Idee, die Einfügung in eine gespeicherte Prozedur zu wickeln und dort zu kürzen! – wageoghe

+0

Sie können 'links (@msg, 1000)' in NLog – Turch

2

Eine Möglichkeit, dies durch die Verwendung regulären Ausdruck Ersatz der Nachricht zu tun ist, die Sie direkt im nlog.config definieren. Ich habe Folgendes verwendet, um auf 500 Zeichen abzuschneiden:

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