/// <summary> /// Creates a custom formatter for the specified members. /// </summary> private static Action <T, TextWriter> CreateCustom(MemberInfo[] forMembers) { var accessors = forMembers.GetMemberAccessors <T>(); if (isException) { // filter out internal values from the Data dictionary, since they're intended to be surfaced in other ways var dataAccessor = accessors.SingleOrDefault(a => a.MemberName == "Data"); if (dataAccessor != null) { var originalGetData = dataAccessor.GetValue; dataAccessor.GetValue = e => ((IDictionary)originalGetData(e)) .Cast <DictionaryEntry>() .Where(de => !de.Key.ToString().StartsWith(ExceptionExtensions.ExceptionDataPrefix)) .ToDictionary(de => de.Key, de => de.Value); } // replace the default stack trace with the full stack trace when present var stackTraceAccessor = accessors.SingleOrDefault(a => a.MemberName == "StackTrace"); if (stackTraceAccessor != null) { stackTraceAccessor.GetValue = e => { var ex = e as Exception; if (ex.Data.Contains(ExceptionExtensions.FullStackTraceKey)) { return(ex.Data[ExceptionExtensions.FullStackTraceKey]); } return(ex.StackTrace); }; } } return((target, writer) => { Formatter.TextFormatter.WriteStartObject(writer); if (writeHeader) { var entry = target as LogEntry; if (entry != null) { Formatter.TextFormatter.WriteLogEntryHeader(entry, writer); } else { Formatter <Type> .Format(typeof(T), writer); } Formatter.TextFormatter.WriteEndHeader(writer); } for (var i = 0; i < accessors.Length; i++) { try { var accessor = accessors[i]; if (accessor.Ignore) { continue; } object value = accessor.GetValue(target); if (accessor.SkipOnNull && value == null) { continue; } Formatter.TextFormatter.WriteStartProperty(writer); writer.Write(accessor.MemberName); Formatter.TextFormatter.WriteNameValueDelimiter(writer); value.FormatTo(writer); Formatter.TextFormatter.WriteEndProperty(writer); if (i < accessors.Length - 1) { Formatter.TextFormatter.WritePropertyDelimiter(writer); } } catch (Exception ex) { ex.RaiseErrorEvent(); if (ex.ShouldThrow()) { throw; } } } Formatter.TextFormatter.WriteEndObject(writer); }); }
/// <summary> /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. /// </summary> /// <returns> /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. /// </returns> public override string ToString() { return(Formatter <LogEntry> .Format(this)); }