2014-04-11 22 views
8

Chcę zapisać niektóre dodatkowe informacje z moim komunikatem o błędzie. Na przykład powinno to być zapytanie użytkownika lub coś innego. Jak mam to zrobić?serializacji obiektów lub kolekcji do zalogowania

Czy są jakieś metody budowania logowania zbiorów, struktur lub obiektów? Czy powinienem serializować go sam?

Odpowiedz

18

Nie, nie ma nic wbudowanego do serializacji obiektów. Jeśli używasz wewnętrznie sformatowanych metod, takich jak Debug<T>(string message, T argument) (możesz zobaczyć klasę NLog.LogEventInfo), do tworzenia sformatowanego komunikatu służy zwykły kod String.Format (to znaczy, że przy każdym parametrze wywoływana jest tylko nazwa ToString()).

Używam Json.NET do serializacji obiektów i kolekcji do JSON. Łatwo jest stworzyć metodę rozszerzenia jak

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

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

a następnie używać go podczas logowania:

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

Ten uproszczony przykład pokazuje, co mi przyszło do po graniu z NLog. W moim rozwiązaniu używam konfiguracji opartej na kodzie, aby zminimalizować duplikaty plików xml nlog.config dla każdego projektu asp.net. Działa z NLog v4.4.1.

Logger statyczny pomocnik: konfiguracja

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

Wyjście dla niestandardowego obiektu:

{ "level": "10", "time": "2017-02-02 16:24:52.3078", "data":{"method":"get","url":"http://localhost:44311/"}} 
Powiązane problemy