/// <summary> /// Simplify the object so as to make handling the serialized /// representation easier. /// </summary> /// <param name="value">The value to simplify (possibly null).</param> /// <returns>A simplified representation.</returns> public static object Simplify(LogEventPropertyValue value) { var scalar = value as ScalarValue; if (scalar != null) return SimplifyScalar(scalar.Value); var dict = value as DictionaryValue; if (dict != null) return dict .Elements .ToDictionary(kv => SimplifyScalar(kv.Key), kv => Simplify(kv.Value)); var seq = value as SequenceValue; if (seq != null) return seq.Elements.Select(Simplify).ToArray(); var str = value as StructureValue; if (str != null) { var props = str.Properties.ToDictionary(p => p.Name, p => Simplify(p.Value)); if (str.TypeTag != null) props["$typeTag"] = str.TypeTag; return props; } return null; }
/// <summary> /// Construct a <see cref="LogEventProperty"/> with the specified name and value. /// </summary> /// <param name="name">The name of the property.</param> /// <param name="value">The value of the property.</param> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentNullException"></exception> public EventProperty(string name, LogEventPropertyValue value) { EnsureValid(name, value); Name = name; Value = value; }
/// <summary> /// Provide a enum representation for a property key /// </summary> /// <remarks>The built-in <c>ToString</c> wraps the string with quotes</remarks> /// <param name="eventPropertyValues">Event property value to provide a string representation</param> /// <param name="propertyKey">Key of the property to return</param> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="eventPropertyValues"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">Thrown when the <paramref name="propertyKey"/> is blank.</exception> /// <exception cref="FormatException"> /// Thrown when the Serilog property value cannot be parsed correctly because the <typeparamref name="TEnum"/> does not present an enumeration type. /// </exception> /// <returns> /// The parsed representation of the Serilog property value as the provided <typeparamref name="TEnum"/> enumeration type; <c>null</c> otherwise. /// </returns> public static TEnum?GetAsEnum <TEnum>(this IReadOnlyDictionary <string, LogEventPropertyValue> eventPropertyValues, string propertyKey) where TEnum : struct { Guard.NotNull(eventPropertyValues, nameof(eventPropertyValues), "Requires a series of event properties to retrieve a Serilog event property as a enumeration representation"); Guard.NotNullOrWhitespace(propertyKey, nameof(propertyKey), "Requires a non-blank property to retrieve a Serilog event property as a enumeration representation"); LogEventPropertyValue logEventPropertyValue = eventPropertyValues.GetValueOrDefault(propertyKey); if (logEventPropertyValue is null) { return(null); } string rawEnum = logEventPropertyValue.ToDecentString(); try { if (Enum.TryParse(rawEnum, out TEnum enumRepresentation)) { return(enumRepresentation); } } catch (ArgumentException exception) { throw new FormatException("Cannot correctly parse the incoming Serilog property value to an enumeration", exception); } return(null); }
/// <summary> /// Simplify the object so as to make handling the serialized /// representation easier. /// </summary> /// <param name="value">The value to simplify (possibly null).</param> /// <param name="format">A format string applied to the value, or null.</param> /// <param name="formatProvider">A format provider to apply to the value, or null to use the default.</param> /// <returns>An Azure Storage entity EntityProperty</returns> public static EntityProperty ToEntityProperty(LogEventPropertyValue value, string format = null, IFormatProvider formatProvider = null) { var scalar = value as ScalarValue; if (scalar != null) return SimplifyScalar(scalar.Value); var dict = value as DictionaryValue; if (dict != null) { return new EntityProperty(dict.ToString(format, formatProvider)); } var seq = value as SequenceValue; if (seq != null) { return new EntityProperty(seq.ToString(format, formatProvider)); } var str = value as StructureValue; if (str != null) { return new EntityProperty(str.ToString(format, formatProvider)); } return null; }
/// <summary> /// Construct a <see cref="LogEventProperty"/> with the specified name and value. /// </summary> /// <param name="name">The name of the property.</param> /// <param name="value">The value of the property.</param> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentNullException"></exception> public LogEventProperty(string name, LogEventPropertyValue value) { if (value == null) throw new ArgumentNullException("value"); if (!IsValidName(name)) throw new ArgumentException("Property name is not valid."); _name = name; _value = value; }
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { var t = value.GetType(); lock (_cacheLock) { if (_ignored.Contains(t)) { result = null; return false; } Func<object, ILogEventPropertyValueFactory, LogEventPropertyValue> cached; if (_cache.TryGetValue(t, out cached)) { result = cached(value, propertyValueFactory); return true; } } var ti = t.GetTypeInfo(); var logAsScalar = ti.GetCustomAttribute<LogAsScalarAttribute>(); if (logAsScalar != null) { lock (_cacheLock) _cache[t] = (o, f) => MakeScalar(o, logAsScalar.IsMutable); } else { var properties = t.GetPropertiesRecursive() .ToList(); if (properties.Any(pi => pi.GetCustomAttribute<LogAsScalarAttribute>() != null || pi.GetCustomAttribute<NotLoggedAttribute>() != null)) { var loggedProperties = properties .Where(pi => pi.GetCustomAttribute<NotLoggedAttribute>() == null) .ToList(); var scalars = loggedProperties .Where(pi => pi.GetCustomAttribute<LogAsScalarAttribute>() != null) .ToDictionary(pi => pi, pi => pi.GetCustomAttribute<LogAsScalarAttribute>().IsMutable); lock (_cacheLock) _cache[t] = (o, f) => MakeStructure(value, loggedProperties, scalars, f, t); } else { lock(_cacheLock) _ignored.Add(t); } } return TryDestructure(value, propertyValueFactory, out result); }
static void EnsureValid(string name, LogEventPropertyValue value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (!LogEventProperty.IsValidName(name)) { throw new ArgumentException("Property name is not valid."); } }
/// <summary> /// Construct a <see cref="LogEventProperty"/> with the specified name and value. /// </summary> /// <param name="name">The name of the property.</param> /// <param name="value">The value of the property.</param> /// <exception cref="ArgumentNullException">When <paramref name="name"/> is <code>null</code></exception> /// <exception cref="ArgumentException">When <paramref name="name"/> is empty or only contains whitespace</exception> /// <exception cref="ArgumentNullException">When <paramref name="value"/> is <code>null</code></exception> public LogEventProperty(string name, LogEventPropertyValue value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } EnsureValidName(name); Name = name; Value = value; }
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { var del = value as Delegate; if (del != null) { result = new ScalarValue(del.ToString()); return true; } result = null; return false; }
public Boolean TryDestructure(Object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { ScalarValue scalar; if (TryConvertToScalar(value, propertyValueFactory, out scalar)) { result = scalar; return true; } result = null; return false; }
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { // These types and their subclasses are property-laden and deep; // most sinks will convert them to strings. if (value is Type || value is MemberInfo) { result = new ScalarValue(value); return true; } result = null; return false; }
public static object Simplify(LogEventPropertyValue value) { var scalar = value as ScalarValue; if (scalar != null) { return SimplifyScalar(scalar.Value); } var dict = value as DictionaryValue; if (dict != null) { var result = new Dictionary<object, object>(); foreach (var element in dict.Elements) { var key = SimplifyScalar(element.Key.Value); if (result.ContainsKey(key)) { Trace.WriteLine( string.Format( "The key {0} is not unique in the provided dictionary after simplification to {1}.", element.Key, key)); return dict.Elements.Select(e => new Dictionary<string, object> { {"Key", SimplifyScalar(e.Key.Value)}, {"Value", Simplify(e.Value)} }).ToArray(); } result.Add(key, Simplify(element.Value)); } return result; } var seq = value as SequenceValue; if (seq != null) { return seq.Elements.Select(Simplify).ToArray(); } var str = value as StructureValue; if (str != null) { var props = str.Properties.ToDictionary(p => p.Name, p => Simplify(p.Value)); if (str.TypeTag != null) { props["$typeTag"] = str.TypeTag; } return props; } return null; }
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { if (value == null) throw new ArgumentNullException("value"); if (!_canApply(value.GetType())) { result = null; return false; } var projected = _projection(value); result = propertyValueFactory.CreatePropertyValue(projected, true); return true; }
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { var type = value.GetType(); if (!type.IsConstructedGenericType || type.GetGenericTypeDefinition() != typeof(Nullable<>)) { result = null; return false; } var dynamicValue = (dynamic)value; result = propertyValueFactory.CreatePropertyValue(dynamicValue.HasValue ? dynamicValue.Value : null, true); return true; }
/// <summary> /// Construct a <see cref="LogEventProperty"/> with the specified name and value. /// </summary> /// <param name="name">The name of the property.</param> /// <param name="value">The value of the property.</param> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentNullException"></exception> public LogEventProperty(string name, LogEventPropertyValue value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (!IsValidName(name)) { throw new ArgumentException("Property name is not valid."); } Name = name; Value = value; }
/// <summary> /// Provides a <c>double</c> representation for a <paramref name="propertyKey"/>. /// </summary> /// <remarks>The built-in <c>ToString</c> wraps the <c>string</c> with quotes.</remarks> /// <param name="eventPropertyValues">The Event property values to provide as a <c>string</c> representation.</param> /// <param name="propertyKey">The key of the property to return.</param> public static double GetAsDouble(this IReadOnlyDictionary <string, LogEventPropertyValue> eventPropertyValues, string propertyKey) { Guard.NotNull(eventPropertyValues, nameof(eventPropertyValues)); LogEventPropertyValue logEventPropertyValue = eventPropertyValues.GetValueOrDefault(propertyKey); string rawDouble = logEventPropertyValue?.ToDecentString(); if (rawDouble != null) { return(Double.Parse(rawDouble, CultureInfo.InvariantCulture)); } return(Double.NaN); }
/// <summary> /// Provide a decent string representation of the event property value /// </summary> /// <remarks>The built-in <c>ToString</c> wraps the string with quotes</remarks> /// <param name="logEventPropertyValue">Event property value to provide a string representation</param> public static string ToDecentString(this LogEventPropertyValue logEventPropertyValue) { Guard.NotNull(logEventPropertyValue, nameof(logEventPropertyValue)); var propertyValueAsString = logEventPropertyValue.ToString().Trim(); if (propertyValueAsString.StartsWith("\"")) { propertyValueAsString = propertyValueAsString.Remove(0, 1); } if (propertyValueAsString.EndsWith("\"")) { propertyValueAsString = propertyValueAsString.Remove(propertyValueAsString.Length - 1); } return(propertyValueAsString); }
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { result = null; var wrapper = value as WrappedJObject; if (wrapper == null) { return false; } var data = wrapper.Value as JObject; if (data == null) { return false; } var values = ReadProperties(data); result = new StructureValue(values); return true; }
/// <summary> /// Removes the structure of <see cref="LogEventPropertyValue"/> implementations introduced /// by Serilog and brings properties closer to the structure of the original object. /// This enables Exceptionless to display the properties in a nicer way. /// </summary> private static object FlattenProperties(LogEventPropertyValue value) { var scalar = value as ScalarValue; if (scalar != null) return scalar.Value; var sequence = value as SequenceValue; if (sequence != null) return sequence.Elements.Select(FlattenProperties); var structure = value as StructureValue; if (structure != null) return structure.Properties.ToDictionary(p => p.Name, p => FlattenProperties(p.Value)); var dictionary = value as DictionaryValue; if (dictionary != null) return dictionary.Elements.ToDictionary(p => p.Key.Value, p => FlattenProperties(p.Value)); return value; }
static string Format(LogEventPropertyValue value) { var formatter = new JsonValueFormatter(); var output = new StringWriter(); formatter.Format(value, output); return output.ToString(); }
/// <summary> /// Simplify the object so as to make handling the serialized /// representation easier. /// </summary> /// <param name="value">The value to simplify (possibly null).</param> /// <returns>A simplified representation.</returns> public static string Simplify(LogEventPropertyValue value) { var scalar = value as ScalarValue; if (scalar != null) return SimplifyScalar(scalar.Value); var dict = value as DictionaryValue; if (dict != null) { var sb = new StringBuilder(); sb.Append("<dictionary>"); foreach (var element in dict.Elements) { var key = SimplifyScalar(element.Key); sb.AppendFormat("<item key='{0}'>{1}</item>", key, Simplify(element.Value)); } sb.Append("</dictionary>"); return sb.ToString(); } var seq = value as SequenceValue; if (seq != null) { var sb = new StringBuilder(); sb.Append("<sequence>"); foreach (var element in seq.Elements) { sb.AppendFormat("<item>{0}</item>", Simplify(element)); } sb.Append("</sequence>"); return sb.ToString(); } var str = value as StructureValue; if (str != null) { var props = str.Properties.ToDictionary(p => p.Name, p => Simplify(p.Value)); var sb = new StringBuilder(); sb.AppendFormat("<structure type='{0}'>", str.TypeTag); foreach (var element in props) { sb.AppendFormat("<property key='{0}'>{1}</property>", element.Key, element.Value); } sb.Append("</structure>"); return sb.ToString(); } return null; }
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { var cwd = value as ICurrentWorkingDirectory; if (cwd == null) { result = null; return false; } var projection = new { CWD = cwd.CWD, IsValid = cwd.IsValid }; result = propertyValueFactory.CreatePropertyValue(projection, true); return true; }
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) { var status = value as IRepositoryStatus; if (status == null) { result = null; return false; } var projection = new { GitDir = status.GitDir, Index = status.Index?.ToString(), Working = status.Working?.ToString(), Branch = status.Branch }; result = propertyValueFactory.CreatePropertyValue(projection, true); return true; }
/// <summary> /// Permit deconstruction of the property into a name/value pair. /// </summary> /// <param name="name">The name of the property.</param> /// <param name="value">The value of the property.</param> public void Deconstruct(out string name, out LogEventPropertyValue value) { name = Name; value = Value; }
/// <summary> /// Simplify the object so as to make handling the serialized /// representation easier. /// </summary> /// <param name="value">The value to simplify (possibly null).</param> /// <param name="options">Options to use during formatting</param> /// <returns>A simplified representation.</returns> public static string Simplify(LogEventPropertyValue value, ColumnOptions.PropertiesColumnOptions options) { var scalar = value as ScalarValue; if (scalar != null) return SimplifyScalar(scalar.Value); var dict = value as DictionaryValue; if (dict != null) { var sb = new StringBuilder(); bool isEmpty = true; foreach (var element in dict.Elements) { var itemValue = Simplify(element.Value, options); if (options.OmitElementIfEmpty && string.IsNullOrEmpty(itemValue)) { continue; } if (isEmpty) { isEmpty = false; if (!options.OmitDictionaryContainerElement) { sb.AppendFormat("<{0}>", options.DictionaryElementName); } } var key = SimplifyScalar(element.Key); if (options.UsePropertyKeyAsElementName) { sb.AppendFormat("<{0}>{1}</{0}>", GetValidElementName(key), itemValue); } else { sb.AppendFormat("<{0} key='{1}'>{2}</{0}>", options.ItemElementName, key, itemValue); } } if (!isEmpty && !options.OmitDictionaryContainerElement) { sb.AppendFormat("</{0}>", options.DictionaryElementName); } return sb.ToString(); } var seq = value as SequenceValue; if (seq != null) { var sb = new StringBuilder(); bool isEmpty = true; foreach (var element in seq.Elements) { var itemValue = Simplify(element, options); if (options.OmitElementIfEmpty && string.IsNullOrEmpty(itemValue)) { continue; } if (isEmpty) { isEmpty = false; if (!options.OmitSequenceContainerElement) { sb.AppendFormat("<{0}>", options.SequenceElementName); } } sb.AppendFormat("<{0}>{1}</{0}>", options.ItemElementName, itemValue); } if (!isEmpty && !options.OmitSequenceContainerElement) { sb.AppendFormat("</{0}>", options.SequenceElementName); } return sb.ToString(); } var str = value as StructureValue; if (str != null) { var props = str.Properties.ToDictionary(p => p.Name, p => Simplify(p.Value, options)); var sb = new StringBuilder(); bool isEmpty = true; foreach (var element in props) { var itemValue = element.Value; if (options.OmitElementIfEmpty && string.IsNullOrEmpty(itemValue)) { continue; } if (isEmpty) { isEmpty = false; if (!options.OmitStructureContainerElement) { if (options.UsePropertyKeyAsElementName) { sb.AppendFormat("<{0}>", GetValidElementName(str.TypeTag)); } else { sb.AppendFormat("<{0} type='{1}'>", options.StructureElementName, str.TypeTag); } } } if (options.UsePropertyKeyAsElementName) { sb.AppendFormat("<{0}>{1}</{0}>", GetValidElementName(element.Key), itemValue); } else { sb.AppendFormat("<{0} key='{1}'>{2}</{0}>", options.PropertyElementName, element.Key, itemValue); } } if (!isEmpty && !options.OmitStructureContainerElement) { if (options.UsePropertyKeyAsElementName) { sb.AppendFormat("</{0}>", GetValidElementName(str.TypeTag)); } else { sb.AppendFormat("</{0}>", options.StructureElementName); } } return sb.ToString(); } return null; }