2014-04-11 8 views
8

Ich möchte einige zusätzliche Informationen mit meiner Fehlermeldung speichern. Zum Beispiel sollte es Benutzerabfrage oder etwas anderes sein. Wie soll ich das machen?Serialize Objekte oder Sammlungen zu protokollieren

Gibt es Build-Methoden zum Protokollieren von Sammlungen, Struktur oder Objekten? Oder ich sollte es selbst serialisieren?

Antwort

18

Nein, zum Serialisieren von Objekten ist nichts eingebaut. Wenn Sie intern formatierte Methoden wie Debug<T>(string message, T argument) verwenden (Sie können die Klasse NLog.LogEventInfo sehen), wird zum Erstellen formatierter Nachrichten einfach String.Format verwendet (d. H. Für jeden Parameter wird nur ToString() aufgerufen).

Ich verwende Json.NET zum Serialisieren von Objekten und Sammlungen zu JSON. Es ist einfach, Extension-Methode wie

public static string ToJson(this object value) 
{ 
    var settings = new JsonSerializerSettings { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    }; 

    return JsonConvert.SerializeObject(value, Formatting.Indented, settings); 
} 

Und dann verwenden Sie es während der Aufzeichnung zu erstellen:

Logger.Debug("Saving person {0}", person.ToJson()); 
4
/** 
* class used to optimize loggers 
* 
* Logger.Trace("info "+bigData.ToString()); 
* Logger.Trace("info {0}",bigData.ToString()); 
* both creates and parses bigData even if Trace is disabled 
* 
* Logger.Trace("info {0}", LazyJsonizer.Create(bigData)); 
* Logger.Trace(LazyJsonizer.Instance, "info {0}", bigData); 
* creates string only if Trace is enabled 
* 
* http://stackoverflow.com/questions/23007377/nlog-serialize-objects-or-collections-to-log 
*/ 
public class LazyJsonizer<T> 
{ 
    T Value; 

    public LazyJsonizer(T value) 
    { 
     Value = value; 
    } 

    override public string ToString() 
    { 
     return LazyJsonizer.Instance.Format(null, Value, null); 
    } 
} 

public class LazyJsonizer : IFormatProvider, ICustomFormatter 
{ 
    static public readonly LazyJsonizer Instance = new LazyJsonizer(); 

    static public LazyJsonizer<T> Create<T>(T value) 
    { 
     return new LazyJsonizer<T>(value); 
    } 

    public object GetFormat(Type formatType) 
    { 
     return this; 
    } 

    public string Format(string format, object arg, IFormatProvider formatProvider) 
    { 
     try 
     { 
      return JsonConvert.SerializeObject(arg); 
     } 
     catch (Exception ex) 
     { 
      return ex.Message; 
     } 
    } 
} 
2

Dieses vereinfachte Beispiel zeigt, was ich kam, nachdem er mit NLog spielen. In meiner Lösung verwende ich Code-basierte Konfiguration, um doppelte xml nlog.config-Dateien für jedes asp.net-Projekt zu minimieren. Funktioniert mit NLog v4.4.1.

Logger statische Helfer:

private static readonly Logger DefaultLogger = LogManager.GetLogger("Application"); 

public static void Debug(Exception exception = null, string message = null, object data = null) 
    => Write(DefaultLogger, LogLevel.Debug, message, exception, data); 

private static void Write(
    Logger logger, 
    LogLevel level, 
    string message = null, 
    Exception exception = null, 
    object data = null) 
{ 
    var eventInfo = new LogEventInfo() 
    { 
     Level = level, 
     Message = message, 
     Exception = exception, 
     Parameters = new[] { data, tag } 
    }; 
    if (data != null) eventInfo.Properties["data"] = data.ToJson(); 
    eventInfo.Properties["level"] = eventInfo.GetLevelCode(); // custom level to int conversion 

    logger.Log(eventInfo); 
} 

FileTarget Konfiguration:

var jsonFileTarget = new FileTarget() 
{ 
    Name = "file_json", 
    Layout = new JsonLayout() 
    { 
     Attributes = 
     { 
      new JsonAttribute("level", "${event-context:item=level}"), 
      new JsonAttribute("time", "${longdate}"), 
      new JsonAttribute("msg", "${message}"), 
      new JsonAttribute("error", "${exception:format=tostring}"), 
      new JsonAttribute("data", "${event-context:item=data}", false), 
     }, 
     RenderEmptyObject = false, 
    }, 
    FileName = $"{LogFile.Directory}/json_{LogFile.Suffix}", // use settings from static LogFile class 
    ArchiveFileName = $"{LogFile.Directory}/json_{LogFile.ArchiveSuffix}", 
    ArchiveAboveSize = LogFile.MaxSize 
}; 

Ausgang für benutzerdefiniertes Objekt:

{ "level": "10", "time": "2017-02-02 16:24:52.3078", "data":{"method":"get","url":"http://localhost:44311/"}} 
Verwandte Themen