Example #1
0
        public void TagObjects_DoubleArray()
        {
            var monitorTags = new TagEnumerationState
            {
                PartBTags = AzMonList.Initialize(),
                PartCTags = AzMonList.Initialize()
            };

            IEnumerable <KeyValuePair <string, object> > tagObjects = new Dictionary <string, object>
            {
                ["doubleArray"] = new double[] { 1.1, 2.2, 3.3 },
            };

            using var activity = CreateTestActivity(tagObjects);
            activity.EnumerateTags(ref monitorTags);

            Assert.Equal(PartBType.Unknown, monitorTags.activityType);
            Assert.Empty(monitorTags.PartBTags);
            Assert.Single(monitorTags.PartCTags);

            Assert.Equal("1.1,2.2,3.3", AzMonList.GetTagValue(ref monitorTags.PartCTags, "doubleArray"));
        }
Example #2
0
        public void TagObjects_BooleanArray()
        {
            var monitorTags = new TagEnumerationState
            {
                MappedTags   = AzMonList.Initialize(),
                UnMappedTags = AzMonList.Initialize()
            };

            IEnumerable <KeyValuePair <string, object> > tagObjects = new Dictionary <string, object>
            {
                ["boolArray"] = new bool[] { true, false, true },
            };

            using var activity = CreateTestActivity(tagObjects);
            monitorTags.ForEach(activity.TagObjects);

            Assert.Equal(OperationType.Unknown, monitorTags.activityType);
            Assert.Empty(monitorTags.MappedTags);
            Assert.Single(monitorTags.UnMappedTags);

            Assert.Equal("True,False,True", AzMonList.GetTagValue(ref monitorTags.UnMappedTags, "boolArray"));
        }
Example #3
0
        public void TagObjects_StringArray()
        {
            var monitorTags = new TagEnumerationState
            {
                MappedTags   = AzMonList.Initialize(),
                UnMappedTags = AzMonList.Initialize()
            };

            IEnumerable <KeyValuePair <string, object> > tagObjects = new Dictionary <string, object>
            {
                ["strArray"] = new string[] { "test1", "test2", "test3" },
            };

            using var activity = CreateTestActivity(tagObjects);
            monitorTags.ForEach(activity.TagObjects);

            Assert.Equal(OperationType.Unknown, monitorTags.activityType);
            Assert.Empty(monitorTags.MappedTags);
            Assert.Single(monitorTags.UnMappedTags);

            Assert.Equal("test1,test2,test3", AzMonList.GetTagValue(ref monitorTags.UnMappedTags, "strArray"));
        }
        public static JaegerSpan ToJaegerSpan(this Activity activity)
        {
            var jaegerTags = new TagEnumerationState
            {
                Tags = PooledList <JaegerTag> .Create(),
            };

            activity.EnumerateTags(ref jaegerTags);

            string peerServiceName = null;

            if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer)
            {
                // If priority = 0 that means peer.service may have already been included in tags
                var addPeerServiceTag = jaegerTags.PeerServicePriority > 0;

                var hostNameOrIpAddress = jaegerTags.HostName ?? jaegerTags.IpAddress;

                // peer.service has not already been included, but net.peer.name/ip and optionally net.peer.port are present
                if ((jaegerTags.PeerService == null || addPeerServiceTag) &&
                    hostNameOrIpAddress != null)
                {
                    peerServiceName = jaegerTags.Port == default
                        ? hostNameOrIpAddress
                        : $"{hostNameOrIpAddress}:{jaegerTags.Port}";

                    // Add the peer.service tag
                    addPeerServiceTag = true;
                }

                if (peerServiceName == null && jaegerTags.PeerService != null)
                {
                    peerServiceName = jaegerTags.PeerService;
                }

                if (peerServiceName != null && addPeerServiceTag)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(SemanticConventions.AttributePeerService, JaegerTagType.STRING, vStr : peerServiceName));
                }
            }

            // The Span.Kind must translate into a tag.
            // See https://opentracing.io/specification/conventions/
            if (activity.Kind != ActivityKind.Internal)
            {
                string spanKind = null;

                if (activity.Kind == ActivityKind.Server)
                {
                    spanKind = "server";
                }
                else if (activity.Kind == ActivityKind.Client)
                {
                    spanKind = "client";
                }
                else if (activity.Kind == ActivityKind.Consumer)
                {
                    spanKind = "consumer";
                }
                else if (activity.Kind == ActivityKind.Producer)
                {
                    spanKind = "producer";
                }

                if (spanKind != null)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("span.kind", JaegerTagType.STRING, vStr : spanKind));
                }
            }

            var activitySource = activity.Source;

            if (!string.IsNullOrEmpty(activitySource.Name))
            {
                PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("library.name", JaegerTagType.STRING, vStr : activitySource.Name));

                if (!string.IsNullOrEmpty(activitySource.Version))
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("library.version", JaegerTagType.STRING, vStr : activitySource.Version));
                }
            }

            var traceId      = Int128.Empty;
            var spanId       = Int128.Empty;
            var parentSpanId = Int128.Empty;

            if (activity.IdFormat == ActivityIdFormat.W3C)
            {
                // TODO: The check above should be enforced by the usage of the exporter. Perhaps enforce at higher-level.
                traceId      = new Int128(activity.TraceId);
                spanId       = new Int128(activity.SpanId);
                parentSpanId = new Int128(activity.ParentSpanId);
            }

            return(new JaegerSpan(
                       peerServiceName: peerServiceName,
                       traceIdLow: traceId.Low,
                       traceIdHigh: traceId.High,
                       spanId: spanId.Low,
                       parentSpanId: parentSpanId.Low,
                       operationName: activity.DisplayName,
                       flags: (activity.Context.TraceFlags & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                       startTime: ToEpochMicroseconds(activity.StartTimeUtc),
                       duration: (long)activity.Duration.TotalMilliseconds * 1000,
                       references: activity.ToJaegerSpanRefs(),
                       tags: jaegerTags.Tags,
                       logs: activity.ToJaegerLogs()));
        }
Example #5
0
        private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000

        public static JaegerSpan ToJaegerSpan(this Activity activity)
        {
            var jaegerTags = new TagEnumerationState
            {
                Tags = PooledList <JaegerTag> .Create(),
            };

            activity.EnumerateTags(ref jaegerTags);

            string peerServiceName = null;

            if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer)
            {
                PeerServiceResolver.Resolve(ref jaegerTags, out peerServiceName, out bool addAsTag);

                if (peerServiceName != null && addAsTag)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(SemanticConventions.AttributePeerService, JaegerTagType.STRING, vStr : peerServiceName));
                }
            }

            // The Span.Kind must translate into a tag.
            // See https://opentracing.io/specification/conventions/
            if (activity.Kind != ActivityKind.Internal)
            {
                string spanKind = null;

                if (activity.Kind == ActivityKind.Server)
                {
                    spanKind = "server";
                }
                else if (activity.Kind == ActivityKind.Client)
                {
                    spanKind = "client";
                }
                else if (activity.Kind == ActivityKind.Consumer)
                {
                    spanKind = "consumer";
                }
                else if (activity.Kind == ActivityKind.Producer)
                {
                    spanKind = "producer";
                }

                if (spanKind != null)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("span.kind", JaegerTagType.STRING, vStr : spanKind));
                }
            }

            var activitySource = activity.Source;

            if (!string.IsNullOrEmpty(activitySource.Name))
            {
                PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("library.name", JaegerTagType.STRING, vStr : activitySource.Name));

                if (!string.IsNullOrEmpty(activitySource.Version))
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("library.version", JaegerTagType.STRING, vStr : activitySource.Version));
                }
            }

            var traceId      = Int128.Empty;
            var spanId       = Int128.Empty;
            var parentSpanId = Int128.Empty;

            if (activity.IdFormat == ActivityIdFormat.W3C)
            {
                // TODO: The check above should be enforced by the usage of the exporter. Perhaps enforce at higher-level.
                traceId      = new Int128(activity.TraceId);
                spanId       = new Int128(activity.SpanId);
                parentSpanId = new Int128(activity.ParentSpanId);
            }

            return(new JaegerSpan(
                       peerServiceName: peerServiceName,
                       traceIdLow: traceId.Low,
                       traceIdHigh: traceId.High,
                       spanId: spanId.Low,
                       parentSpanId: parentSpanId.Low,
                       operationName: activity.DisplayName,
                       flags: (activity.Context.TraceFlags & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                       startTime: ToEpochMicroseconds(activity.StartTimeUtc),
                       duration: (long)activity.Duration.TotalMilliseconds * 1000,
                       references: activity.ToJaegerSpanRefs(),
                       tags: jaegerTags.Tags,
                       logs: activity.ToJaegerLogs()));
        }
        public RemoteDependencyData(int version, Activity activity, ref TagEnumerationState monitorTags) : base(version)
        {
            string httpUrl = null;
            string dependencyName;

            if (monitorTags.activityType == PartBType.Http)
            {
                httpUrl        = monitorTags.PartBTags.GetDependencyUrl();
                dependencyName = monitorTags.PartBTags.GetHttpDependencyName(httpUrl) ?? activity.DisplayName;
            }
            else
            {
                dependencyName = activity.DisplayName;
            }

            Name     = dependencyName;
            Id       = activity.Context.SpanId.ToHexString();
            Duration = activity.Duration.ToString("c", CultureInfo.InvariantCulture);
            Success  = activity.GetStatus().StatusCode != StatusCode.Error;

            switch (monitorTags.activityType)
            {
            case PartBType.Http:
                Data       = httpUrl;
                Target     = monitorTags.PartBTags.GetDependencyTarget(PartBType.Http);
                Type       = "Http";
                ResultCode = AzMonList.GetTagValue(ref monitorTags.PartBTags, SemanticConventions.AttributeHttpStatusCode)?.ToString() ?? "0";
                break;

            case PartBType.Db:
                var depDataAndType = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeDbStatement, SemanticConventions.AttributeDbSystem);
                Data   = depDataAndType[0]?.ToString();
                Target = monitorTags.PartBTags.GetDbDependencyTarget();
                Type   = SqlDbs.Contains(depDataAndType[1]?.ToString()) ? "SQL" : depDataAndType[1]?.ToString();
                break;

            case PartBType.Rpc:
                var depInfo = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeRpcService, SemanticConventions.AttributeRpcSystem, SemanticConventions.AttributeRpcStatus);
                Data       = depInfo[0]?.ToString();
                Type       = depInfo[1]?.ToString();
                ResultCode = depInfo[2]?.ToString();
                break;

            case PartBType.Messaging:
                depDataAndType = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeMessagingUrl, SemanticConventions.AttributeMessagingSystem);
                Data           = depDataAndType[0]?.ToString();
                Type           = depDataAndType[1]?.ToString();
                break;
            }

            if (activity.Kind == ActivityKind.Internal && activity.Parent != null)
            {
                Type = "InProc";
            }

            Properties   = new ChangeTrackingDictionary <string, string>();
            Measurements = new ChangeTrackingDictionary <string, double>();

            TraceHelper.AddActivityLinksToPartCTags(activity.Links, ref monitorTags.PartCTags);
            TraceHelper.AddPropertiesToTelemetry(Properties, ref monitorTags.PartCTags);
        }
        private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000

        public static JaegerSpan ToJaegerSpan(this Activity activity)
        {
            var jaegerTags = new TagEnumerationState
            {
                Tags = PooledList <JaegerTag> .Create(),
            };

            activity.EnumerateTags(ref jaegerTags);

            if (activity.Status != ActivityStatusCode.Unset)
            {
                if (activity.Status == ActivityStatusCode.Ok)
                {
                    PooledList <JaegerTag> .Add(
                        ref jaegerTags.Tags,
                        new JaegerTag(SpanAttributeConstants.StatusCodeKey, JaegerTagType.STRING, vStr : "OK"));
                }
                else
                {
                    PooledList <JaegerTag> .Add(
                        ref jaegerTags.Tags,
                        new JaegerTag(SpanAttributeConstants.StatusCodeKey, JaegerTagType.STRING, vStr : "ERROR"));

                    PooledList <JaegerTag> .Add(
                        ref jaegerTags.Tags,
                        new JaegerTag(JaegerErrorFlagTagName, JaegerTagType.BOOL, vBool : true));

                    PooledList <JaegerTag> .Add(
                        ref jaegerTags.Tags,
                        new JaegerTag(SpanAttributeConstants.StatusDescriptionKey, JaegerTagType.STRING, vStr : activity.StatusDescription ?? string.Empty));
                }
            }
            else if (jaegerTags.StatusCode.HasValue && jaegerTags.StatusCode != StatusCode.Unset)
            {
                PooledList <JaegerTag> .Add(
                    ref jaegerTags.Tags,
                    new JaegerTag(
                        SpanAttributeConstants.StatusCodeKey,
                        JaegerTagType.STRING,
                        vStr : StatusHelper.GetTagValueForStatusCode(jaegerTags.StatusCode.Value)));

                if (jaegerTags.StatusCode == StatusCode.Error)
                {
                    PooledList <JaegerTag> .Add(
                        ref jaegerTags.Tags,
                        new JaegerTag(JaegerErrorFlagTagName, JaegerTagType.BOOL, vBool : true));

                    PooledList <JaegerTag> .Add(
                        ref jaegerTags.Tags,
                        new JaegerTag(SpanAttributeConstants.StatusDescriptionKey, JaegerTagType.STRING, vStr : jaegerTags.StatusDescription ?? string.Empty));
                }
            }

            string peerServiceName = null;

            if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer)
            {
                PeerServiceResolver.Resolve(ref jaegerTags, out peerServiceName, out bool addAsTag);

                if (peerServiceName != null && addAsTag)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(SemanticConventions.AttributePeerService, JaegerTagType.STRING, vStr : peerServiceName));
                }
            }

            // The Span.Kind must translate into a tag.
            // See https://opentracing.io/specification/conventions/
            if (activity.Kind != ActivityKind.Internal)
            {
                string spanKind = null;

                if (activity.Kind == ActivityKind.Server)
                {
                    spanKind = "server";
                }
                else if (activity.Kind == ActivityKind.Client)
                {
                    spanKind = "client";
                }
                else if (activity.Kind == ActivityKind.Consumer)
                {
                    spanKind = "consumer";
                }
                else if (activity.Kind == ActivityKind.Producer)
                {
                    spanKind = "producer";
                }

                if (spanKind != null)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("span.kind", JaegerTagType.STRING, vStr : spanKind));
                }
            }

            var activitySource = activity.Source;

            if (!string.IsNullOrEmpty(activitySource.Name))
            {
                PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("otel.library.name", JaegerTagType.STRING, vStr : activitySource.Name));

                if (!string.IsNullOrEmpty(activitySource.Version))
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("otel.library.version", JaegerTagType.STRING, vStr : activitySource.Version));
                }
            }

            var traceId      = Int128.Empty;
            var spanId       = Int128.Empty;
            var parentSpanId = Int128.Empty;

            if (activity.IdFormat == ActivityIdFormat.W3C)
            {
                // TODO: The check above should be enforced by the usage of the exporter. Perhaps enforce at higher-level.
                traceId = new Int128(activity.TraceId);
                spanId  = new Int128(activity.SpanId);
                if (activity.ParentSpanId != default)
                {
                    parentSpanId = new Int128(activity.ParentSpanId);
                }
            }

            return(new JaegerSpan(
                       peerServiceName: peerServiceName,
                       traceIdLow: traceId.Low,
                       traceIdHigh: traceId.High,
                       spanId: spanId.Low,
                       parentSpanId: parentSpanId.Low,
                       operationName: activity.DisplayName,
                       flags: (activity.Context.TraceFlags & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                       startTime: ToEpochMicroseconds(activity.StartTimeUtc),
                       duration: activity.Duration.Ticks / TicksPerMicrosecond,
                       references: activity.ToJaegerSpanRefs(),
                       tags: jaegerTags.Tags,
                       logs: activity.ToJaegerLogs()));
        }