2014-04-11 14 views
8

Desidero salvare alcune informazioni addizionali con il mio messaggio di errore. Ad esempio dovrebbe essere la query dell'utente o qualcos'altro. Come dovrei farlo?serializza oggetti o raccolte per il registro

Esistono metodi di compilazione per la registrazione di raccolte, structurest o oggetti? O dovrei serializzarlo da solo?

risposta

18

No, non c'è nulla di built-in per la serializzazione di oggetti. Quando si utilizzano metodi formattati come Debug<T>(string message, T argument) internamente (è possibile vedere la classe NLog.LogEventInfo), semplice String.Format viene utilizzato per la creazione di un messaggio formattato (ad esempio, solo ToString() viene richiamato su ogni parametro).

Io uso Json.NET per serializzare oggetti e raccolte su JSON. E 'facile creare metodo di estensione come

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

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

E poi utilizzarlo durante la registrazione:

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

questo esempio semplificato mostra che cosa sono venuto a dopo aver giocato con NLog. Nella mia soluzione utilizzo la configurazione basata su codice al fine di mitigare i file xml nlog.config duplicati per ogni progetto asp.net. Funziona con NLog v4.4.1.

Logger helper statica: configurazione

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:

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 
}; 

Uscita per oggetto personalizzato:

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