示例#1
0
        private static void AddStackFrameData(this IHerculesTagsBuilder builder, StackFrame frame)
        {
            var method = frame.GetMethod();

            if (method != null)
            {
                builder.AddValue(StackFrameTagNames.Function, ExceptionsNormalizer.Normalize(method.Name));
                if (method.DeclaringType != null)
                {
                    builder.AddValue(StackFrameTagNames.Type, ExceptionsNormalizer.Normalize(method.DeclaringType.FullName));
                }
            }

            var fileName = frame.GetFileName();

            if (!string.IsNullOrEmpty(fileName))
            {
                builder.AddValue(StackFrameTagNames.File, fileName);
            }

            var lineNumber = frame.GetFileLineNumber();

            if (lineNumber > 0)
            {
                builder.AddValue(StackFrameTagNames.Line, lineNumber);
            }

            var columnNumber = frame.GetFileColumnNumber();

            if (columnNumber > 0)
            {
                builder.AddValue(StackFrameTagNames.Column, columnNumber);
            }
        }
 public static IHerculesTagsBuilder AddVectorOfContainers <TValue>(
     [NotNull] this IHerculesTagsBuilder builder,
     [NotNull] string key,
     [NotNull] IReadOnlyList <TValue> values,
     [NotNull] Action <IHerculesTagsBuilder, TValue> valueBuilder)
 => builder.AddVectorOfContainers(
     key,
     values.Select(x => new Action <IHerculesTagsBuilder>(b => valueBuilder(b, x))).ToArray());
        private void WriteTagsWithAllDataTypes(IHerculesTagsBuilder builder)
        {
            var guid    = Guid.NewGuid();
            var @bool   = true;
            var @byte   = (byte)42;
            var @double = Math.PI;
            var @float  = (float)@double;
            var @int    = int.MaxValue;
            var @long   = long.MinValue;
            var @short  = short.MinValue;
            var @string = "dotnet";

            var guidVec   = new[] { Guid.NewGuid(), Guid.NewGuid() };
            var boolVec   = new[] { true, false };
            var byteVec   = new[] { (byte)42, (byte)25 };
            var doubleVec = new[] { Math.PI, Math.E };
            var floatVec  = doubleVec.Select(x => (float)x).ToArray();
            var intVec    = new[] { 1337, 31337, int.MaxValue, int.MinValue };
            var longVec   = new[] { long.MaxValue, long.MinValue, (long)1e18 + 1 };
            var shortVec  = new short[] { 1000, 2000 };
            var stringVec = new[] { "dotnet", "hercules" };

            builder
            .AddNull("null")
            .AddValue("guid", guid)
            .AddValue("bool", @bool)
            .AddValue("byte", @byte)
            .AddValue("double", @double)
            .AddValue("float", @float)
            .AddValue("int", @int)
            .AddValue("long", @long)
            .AddValue("short", @short)
            .AddValue("string", @string)
            .AddVector("guidVec", guidVec)
            .AddVector("boolVec", boolVec)
            .AddVector("byteVec", byteVec)
            .AddVector("doubleVec", doubleVec)
            .AddVector("floatVec", floatVec)
            .AddVector("intVec", intVec)
            .AddVector("longVec", longVec)
            .AddVector("shortVec", shortVec)
            .AddVector("stringVec", stringVec)
            .AddVector("emptyVec", new int[0])
            .AddContainer(
                "container",
                b => b
                .AddValue("inner", "x")
                .AddVector("innerVec", new[] { 1, 2, 3 }))
            .AddVectorOfContainers(
                "containerVec",
                new Action <IHerculesTagsBuilder>[]
            {
                b => b
                .AddValue("inner", "y")
                .AddVector("innerVec", new long[] { 1, 3, 5 })
            })
            .AddVectorOfContainers("emptyContainerVec", new Action <IHerculesTagsBuilder> [0]);
        }
        public static IHerculesTagsBuilder AddVector(this IHerculesTagsBuilder builder, string key, HerculesVector vector)
        {
            switch (vector.ElementType)
            {
            case HerculesValueType.String:
                builder.AddVector(key, vector.AsStringList);
                break;

            case HerculesValueType.Long:
                builder.AddVector(key, vector.AsLongList);
                break;

            case HerculesValueType.Guid:
                builder.AddVector(key, vector.AsGuidList);
                break;

            case HerculesValueType.Container:
                builder.AddVectorOfContainers(key, vector.AsContainerList, (tagsBuilder, tags) => tagsBuilder.AddTags(tags));
                break;

            case HerculesValueType.Int:
                builder.AddVector(key, vector.AsIntList);
                break;

            case HerculesValueType.Double:
                builder.AddVector(key, vector.AsDoubleList);
                break;

            case HerculesValueType.Bool:
                builder.AddVector(key, vector.AsBoolList);
                break;

            case HerculesValueType.Byte:
                builder.AddVector(key, vector.AsByteList);
                break;

            case HerculesValueType.Short:
                builder.AddVector(key, vector.AsShortList);
                break;

            case HerculesValueType.Float:
                builder.AddVector(key, vector.AsFloatList);
                break;

            case HerculesValueType.Null:
                builder.AddNull(key);
                break;

            case HerculesValueType.Vector:
                throw new NotSupportedException("Support of nested vectors is not implemented.");

            default:
                throw new ArgumentOutOfRangeException(nameof(vector.ElementType), vector.ElementType, "Unknown vector element type.");
            }

            return(builder);
        }
        private static void BuildAnnotationsContainer(IHerculesTagsBuilder builder, ISpan span, IFormatProvider formatProvider)
        {
            foreach (var pair in span.Annotations)
            {
                if (builder.TryAddObject(pair.Key, pair.Value))
                {
                    continue;
                }

                builder.AddValue(pair.Key, ObjectValueFormatter.Format(pair.Value, formatProvider: formatProvider));
            }
        }
示例#6
0
        public static IHerculesTagsBuilder AddExceptionData(
            this IHerculesTagsBuilder builder,
            Exception exception)
        {
            builder
            .AddValue(ExceptionTagNames.Message, exception.Message)
            .AddValue(ExceptionTagNames.Type, ExceptionsNormalizer.Normalize(exception.GetType().FullName));

            var stackFrames = new StackTrace(exception, true).GetFrames();

            if (stackFrames != null)
            {
                builder.AddVectorOfContainers(
                    ExceptionTagNames.StackFrames,
                    stackFrames,
                    (tagsBuilder, frame) => tagsBuilder.AddStackFrameData(frame));
            }

            var innerExceptions = new List <Exception>();

            if (exception is AggregateException aggregateException)
            {
                innerExceptions.AddRange(aggregateException.InnerExceptions);
            }
            else if (exception.InnerException != null)
            {
                innerExceptions.Add(exception.InnerException);
            }

            if (innerExceptions.Count > 0)
            {
                builder.AddVectorOfContainers(
                    ExceptionTagNames.InnerExceptions,
                    innerExceptions,
                    (tagsBuilder, e) => tagsBuilder.AddExceptionData(e));
            }

            return(builder);
        }
示例#7
0
        public static IHerculesTagsBuilder AddProperties(
            this IHerculesTagsBuilder builder,
            LogEvent @event,
            IReadOnlyCollection <string> filteredProperties,
            IFormatProvider formatProvider)
        {
            foreach (var keyValuePair in @event.Properties !)
            {
                var key = keyValuePair.Key;
                if (IsPositionalName(key))
                {
                    continue;
                }
                if (filteredProperties?.Contains(key) == true)
                {
                    continue;
                }

                var value = keyValuePair.Value;

                if (key == WellKnownProperties.OperationContext && value is OperationContextValue operationContextValue)
                {
                    value = operationContextValue.Select(t => OperationContextValueFormatter.Format(@event, t, null, formatProvider)).ToArray();
                }

                if (builder.TryAddObject(key, value))
                {
                    continue;
                }

                var format = value is DateTime || value is DateTimeOffset ? "O" : null;

                builder.AddValue(key, ObjectValueFormatter.Format(value, format));
            }

            return(builder);
        }
        public static IHerculesTagsBuilder AddTags(this IHerculesTagsBuilder builder, HerculesTags tags)
        {
            foreach (var tag in tags)
            {
                var key   = tag.Key;
                var value = tag.Value;

                switch (value.Type)
                {
                case HerculesValueType.String:
                    builder.AddValue(key, value.AsString);
                    break;

                case HerculesValueType.Long:
                    builder.AddValue(key, value.AsLong);
                    break;

                case HerculesValueType.Guid:
                    builder.AddValue(key, value.AsGuid);
                    break;

                case HerculesValueType.Container:
                    builder.AddContainer(key, tagsBuilder => tagsBuilder.AddTags(value.AsContainer));
                    break;

                case HerculesValueType.Int:
                    builder.AddValue(key, value.AsInt);
                    break;

                case HerculesValueType.Double:
                    builder.AddValue(key, value.AsDouble);
                    break;

                case HerculesValueType.Bool:
                    builder.AddValue(key, value.AsBool);
                    break;

                case HerculesValueType.Null:
                    builder.AddNull(key);
                    break;

                case HerculesValueType.Byte:
                    builder.AddValue(key, value.AsByte);
                    break;

                case HerculesValueType.Short:
                    builder.AddValue(key, value.AsShort);
                    break;

                case HerculesValueType.Float:
                    builder.AddValue(key, value.AsFloat);
                    break;

                case HerculesValueType.Vector:
                    builder.AddVector(key, value.AsVector);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(value.Type), value.Type, "Unknown tag type.");
                }
            }

            return(builder);
        }
        private static void ReadContainer(IBinaryReader reader, IHerculesTagsBuilder builder)
        {
            var tagsCount = reader.ReadInt16();

            for (var i = 0; i < tagsCount; i++)
            {
                var key       = reader.ReadShortString();
                var valueType = (TagType)reader.ReadByte();

                switch (valueType)
                {
                case TagType.String:
                    builder.AddValue(key, reader.ReadString());
                    break;

                case TagType.Long:
                    builder.AddValue(key, reader.ReadInt64());
                    break;

                case TagType.Uuid:
                    builder.AddValue(key, reader.ReadGuid());
                    break;

                case TagType.Container:
                    builder.AddContainer(key, b => ReadContainer(reader, b));
                    break;

                case TagType.Integer:
                    builder.AddValue(key, reader.ReadInt32());
                    break;

                case TagType.Double:
                    builder.AddValue(key, reader.ReadDouble());
                    break;

                case TagType.Flag:
                    builder.AddValue(key, reader.ReadBool());
                    break;

                case TagType.Null:
                    builder.AddNull(key);
                    break;

                case TagType.Byte:
                    builder.AddValue(key, reader.ReadByte());
                    break;

                case TagType.Short:
                    builder.AddValue(key, reader.ReadInt16());
                    break;

                case TagType.Float:
                    builder.AddValue(key, reader.ReadFloat());
                    break;

                case TagType.Vector:
                    ReadVector(reader, builder, key);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(valueType), valueType, "Unexpected tag value type.");
                }
            }
        }
        private static void ReadVector(IBinaryReader reader, IHerculesTagsBuilder builder, string key)
        {
            var elementType = (TagType)reader.ReadByte();

            switch (elementType)
            {
            case TagType.String:
                builder.AddVector(key, reader.ReadArray(r => r.ReadString()));
                break;

            case TagType.Long:
                builder.AddVector(key, reader.ReadArray(r => r.ReadInt64()));
                break;

            case TagType.Uuid:
                builder.AddVector(key, reader.ReadArray(r => r.ReadGuid()));
                break;

            case TagType.Container:
                var elementsCount = reader.ReadInt32();
                var valueBuilder  = new Action <IHerculesTagsBuilder>(b => ReadContainer(reader, b));
                var valueBuilders = new Action <IHerculesTagsBuilder> [elementsCount];

                for (var i = 0; i < elementsCount; i++)
                {
                    valueBuilders[i] = valueBuilder;
                }

                builder.AddVectorOfContainers(key, valueBuilders);
                break;

            case TagType.Integer:
                builder.AddVector(key, reader.ReadArray(r => r.ReadInt32()));
                break;

            case TagType.Double:
                builder.AddVector(key, reader.ReadArray(r => r.ReadDouble()));
                break;

            case TagType.Flag:
                builder.AddVector(key, reader.ReadArray(r => r.ReadBool()));
                break;

            case TagType.Byte:
                builder.AddVector(key, reader.ReadByteArray());
                break;

            case TagType.Short:
                builder.AddVector(key, reader.ReadArray(r => r.ReadInt16()));
                break;

            case TagType.Float:
                builder.AddVector(key, reader.ReadArray(r => r.ReadFloat()));
                break;

            case TagType.Vector:
                throw new NotSupportedException("Nested vectors are not supported yet.");

            case TagType.Null:
                throw new NotSupportedException("Vectors of nulls are not supported yet.");

            default:
                throw new ArgumentOutOfRangeException(nameof(elementType), elementType, "Unexpected vector element type.");
            }
        }
        /// <summary>
        /// <para>Attempts to add a tag with given <paramref name="key"/> and <paramref name="value"/>.</para>
        /// <para><paramref name="value"/> representation depends on its runtime type.</para>
        /// </summary>
        /// <returns><c>true</c> when <paramref name="value"/> runtime type is natively supported by Hercules, <c>false</c> otherwise.</returns>
        public static bool TryAddObject([NotNull] this IHerculesTagsBuilder builder, [NotNull] string key, [CanBeNull] object value)
        {
            switch (value)
            {
            case string stringValue:
                builder.AddValue(key, stringValue);
                return(true);

            case int intValue:
                builder.AddValue(key, intValue);
                return(true);

            case long longValue:
                builder.AddValue(key, longValue);
                return(true);

            case Guid GuidValue:
                builder.AddValue(key, GuidValue);
                return(true);

            case bool boolValue:
                builder.AddValue(key, boolValue);
                return(true);

            case double doubleValue:
                builder.AddValue(key, doubleValue);
                return(true);

            case byte byteValue:
                builder.AddValue(key, byteValue);
                return(true);

            case short shortValue:
                builder.AddValue(key, shortValue);
                return(true);

            case float floatValue:
                builder.AddValue(key, floatValue);
                return(true);

            case null:
                builder.AddNull(key);
                return(true);
            }

            if (value is IEnumerable)
            {
                switch (value)
                {
                case IReadOnlyList <string> stringList:
                    builder.AddVector(key, stringList);
                    return(true);

                case IReadOnlyList <int> intList:
                    builder.AddVector(key, intList);
                    return(true);

                case IReadOnlyList <long> longList:
                    builder.AddVector(key, longList);
                    return(true);

                case IReadOnlyList <Guid> GuidList:
                    builder.AddVector(key, GuidList);
                    return(true);

                case IReadOnlyList <bool> boolList:
                    builder.AddVector(key, boolList);
                    return(true);

                case IReadOnlyList <double> doubleList:
                    builder.AddVector(key, doubleList);
                    return(true);

                case IReadOnlyList <byte> byteList:
                    builder.AddVector(key, byteList);
                    return(true);

                case IReadOnlyList <short> shortList:
                    builder.AddVector(key, shortList);
                    return(true);

                case IReadOnlyList <float> floatList:
                    builder.AddVector(key, floatList);
                    return(true);
                }
            }

            return(false);
        }