The value associated with a LogEventProperty. Divided into scalar, sequence and structure values to direct serialization into various formats.
Inheritance: IFormattable
        /// <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;
        }
Example #5
0
        /// <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.");
     }
 }
Example #8
0
        /// <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;
        }
Example #15
0
        /// <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();
 }
Example #21
0
        /// <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;
        }
Example #22
0
            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;
            }
Example #23
0
            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;
        }