2013-10-14 4 views
7

Sto registrando i miei messaggi in un campo di database con una dimensione massima di 1000 caratteri. Attualmente, se provo a registrare un messaggio (che spesso contiene informazioni sulle eccezioni con traccia dello stack, contenuto della richiesta HTTP, ecc.) Più grande di 1000 caratteri, l'inserto fallisce e NLog (come dovrebbe) ignora in silenzio e continua.NLog auto truncate messages

C'è qualcosa che posso inserire nel mio file NLog.config per dichiarare che la lunghezza del messaggio deve sempre essere troncata quindi non è maggiore di 1000 caratteri?

Punti bonus se puoi dirmi come contrassegnare con grazia i messaggi troncati sostituendo gli ultimi caratteri prima del limite di 1000 caratteri con qualcosa come "[... Troncato]".

Non riesco a credere Non riesco a trovare facilmente questo con alcuni googling. Spero di non dover scrivere il mio riproduttore?

risposta

5

Non so di un costruito in modo per farlo. Invece, vorrei scrivere un LayoutRenderer (in realtà, un WrapperLayoutRenderer). Non è difficile.

Qualcosa di simile (non testato) dovrebbe farlo:

[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

Grazie. Sicuramente sembra facile, ma speravo di evitarlo soprattutto perché finivo con questa fastidiosa classe che tutti i miei progetti che usano questo sistema di registrazione dovrebbero avere una dipendenza, e non sembra che sia vale la manutenzione –

2

In log4indirei left (@msg, 1000) nell'istruzione di inserimento per garantire che il messaggio si adatti alla colonna del database. Probabilmente puoi fare qualcosa di simile in nlog.

in SQL Server si può costruire un inserto in .. Seleziona da-dichiarazione che utilizzano questo frammento:

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

Grazie. Quella cosa 'left (@msg, 1000)' in log4net sarebbe perfetta:/ho finito per fare praticamente quello che hai suggerito, lato SQL, in una stored procedure che avvolge l'inserto. Vorrei poter contrassegnare entrambi come la risposta accettata ma, anche se ho finito per fare ciò che mi hai suggerito, sento che la risposta di wageoghe è più utile nel caso generale. –

+0

Questa è davvero una buona idea, avvolgere l'inserto in una stored procedure e fare il troncamento lì! – wageoghe

+0

puoi fare 'left (@msg, 1000)' in NLog – Turch

2

Un modo per farlo è quello di utilizzare la sostituzione regolare espressione del messaggio, che è possibile definire in pieno nlog.config. Ho usato quanto segue per troncare fino a 500 caratteri:

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