public static JaegerSpanRef ToJaegerSpanRef(this in ActivityLink link)
        {
            var traceId = new Int128(link.Context.TraceId);
            var spanId  = new Int128(link.Context.SpanId);

            return(new JaegerSpanRef(JaegerSpanRefType.CHILD_OF, traceId.Low, traceId.High, spanId.Low));
        }
        public static JaegerSpanRef ToJaegerSpanRef(this in ActivityLink link)
        {
            var traceId = new Int128(link.Context.TraceId);
            var spanId  = new Int128(link.Context.SpanId);

            // Assume FOLLOWS_FROM for links, mirrored from Java: https://github.com/open-telemetry/opentelemetry-java/pull/481#discussion_r312577862
            var refType = JaegerSpanRefType.FOLLOWS_FROM;

            return(new JaegerSpanRef(refType, traceId.Low, traceId.High, spanId.Low));
        }
        public static JaegerSpanRef ToJaegerSpanRef(this Link link)
        {
            var traceId = Int128.Empty;
            var spanId  = Int128.Empty;

            if (link != default)
            {
                traceId = new Int128(link.Context.TraceId);
                spanId  = new Int128(link.Context.SpanId);
            }

            return(new JaegerSpanRef(JaegerSpanRefType.CHILD_OF, traceId.Low, traceId.High, spanId.Low));
        }
        public static JaegerSpanRef ToJaegerSpanRef(this Link link)
        {
            var traceId = Int128.Empty;
            var spanId  = Int128.Empty;

            if (link != null)
            {
                traceId = new Int128(link.Context.TraceId);
                spanId  = new Int128(link.Context.SpanId);
            }

            return(new JaegerSpanRef
            {
                TraceIdHigh = traceId.High,
                TraceIdLow = traceId.Low,
                SpanId = spanId.Low,
                RefType = JaegerSpanRefType.CHILD_OF,
            });
        }
Beispiel #5
0
        private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000

        public static JaegerSpan ToJaegerSpan(this Span span)
        {
            IEnumerable <JaegerTag> jaegerTags = null;

            if (span?.Attributes is IEnumerable <KeyValuePair <string, object> > attributeMap)
            {
                jaegerTags = attributeMap.Select(a => a.ToJaegerTag()).AsEnumerable();
            }

            IEnumerable <JaegerLog> jaegerLogs = null;

            if (span?.Events != null)
            {
                jaegerLogs = span.Events.Select(e => e.ToJaegerLog()).AsEnumerable();
            }

            IEnumerable <JaegerSpanRef> refs = null;

            if (span?.Links != null)
            {
                refs = span.Links.Select(l => l.ToJaegerSpanRef()).Where(l => l != null).AsEnumerable();
            }

            var parentSpanId = new Int128(span.ParentSpanId);

            var traceId = span?.Context?.TraceId == null ? Int128.Empty : new Int128(span.Context.TraceId);
            var spanId  = span?.Context?.SpanId == null ? Int128.Empty : new Int128(span.Context.SpanId);

            return(new JaegerSpan
            {
                TraceIdHigh = traceId.High,
                TraceIdLow = traceId.Low,
                SpanId = spanId.Low,
                ParentSpanId = parentSpanId.Low,
                OperationName = span.Name,
                References = refs,
                Flags = (span.Context.TraceOptions & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                StartTime = ToEpochMicroseconds(span.StartTimestamp),
                Duration = ToEpochMicroseconds(span.EndTimestamp) - ToEpochMicroseconds(span.StartTimestamp),
                JaegerTags = jaegerTags,
                Logs = jaegerLogs,
            });
        }
        public static JaegerSpan ToJaegerSpan(this Activity activity)
        {
            var jaegerTags = new TagState
            {
                Tags = PooledList <JaegerTag> .Create(),
            };

            DictionaryEnumerator <string, string, TagState> .AllocationFreeForEach(
                activity.Tags,
                ref jaegerTags,
                ProcessActivityTagRef);

            string peerServiceName = null;

            if ((activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer) && jaegerTags.PeerService != null)
            {
                // Send peer.service for remote calls.
                peerServiceName = jaegerTags.PeerService;

                // If priority = 0 that means peer.service was already included in tags.
                if (jaegerTags.PeerServicePriority > 0)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(SpanAttributeConstants.PeerServiceKey, 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.Links.ToJaegerSpanRefs(),
                       tags: jaegerTags.Tags,
                       logs: activity.Events.ToJaegerLogs()));
        }
        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()));
        }
Beispiel #8
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()));
        }
Beispiel #9
0
        private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000

        public static JaegerSpan ToJaegerSpan(this SpanData span)
        {
            List <JaegerTag> jaegerTags = null;

            if (span.Attributes is IEnumerable <KeyValuePair <string, object> > attributeMap)
            {
                jaegerTags = attributeMap.Select(a => a.ToJaegerTag()).ToList();
            }

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

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

                if (spanKind != null)
                {
                    jaegerTags.Add(new JaegerTag
                    {
                        Key   = "span.kind",
                        VType = JaegerTagType.STRING,
                        VStr  = spanKind,
                    });
                }
            }

            IEnumerable <JaegerLog> jaegerLogs = null;

            if (span.Events != null)
            {
                jaegerLogs = span.Events.Select(e => e.ToJaegerLog()).AsEnumerable();
            }

            IEnumerable <JaegerSpanRef> refs = null;

            if (span.Links != null)
            {
                refs = span.Links.Select(l => l.ToJaegerSpanRef()).Where(l => l != null).AsEnumerable();
            }

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

            if (span.Context.IsValid)
            {
                traceId      = new Int128(span.Context.TraceId);
                spanId       = new Int128(span.Context.SpanId);
                parentSpanId = new Int128(span.ParentSpanId);
            }

            return(new JaegerSpan
            {
                TraceIdHigh = traceId.High,
                TraceIdLow = traceId.Low,
                SpanId = spanId.Low,
                ParentSpanId = parentSpanId.Low,
                OperationName = span.Name,
                References = refs,
                Flags = (span.Context.TraceOptions & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                StartTime = ToEpochMicroseconds(span.StartTimestamp),
                Duration = ToEpochMicroseconds(span.EndTimestamp) - ToEpochMicroseconds(span.StartTimestamp),
                JaegerTags = jaegerTags,
                Logs = jaegerLogs,
            });
        }
        public static JaegerSpan ToJaegerSpan(this SpanData span)
        {
            var jaegerTags = new TagState
            {
                Tags = PooledList <JaegerTag> .Create(),
            };

            DictionaryEnumerator <string, object, TagState> .AllocationFreeForEach(
                span.Attributes,
                ref jaegerTags,
                ProcessAttributeRef);

            // Send peer.service for remote calls. If priority = 0 that means peer.service was already included.
            if ((span.Kind == SpanKind.Client || span.Kind == SpanKind.Producer) &&
                jaegerTags.PeerService != null &&
                jaegerTags.PeerServicePriority > 0)
            {
                PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("peer.service", JaegerTagType.STRING, vStr : jaegerTags.PeerService));
            }

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

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

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

            DictionaryEnumerator <string, object, TagState> .AllocationFreeForEach(
                span.LibraryResource?.Attributes ?? Array.Empty <KeyValuePair <string, object> >(),
                ref jaegerTags,
                ProcessLibraryAttributeRef);

            var status = span.Status;

            if (status.IsValid)
            {
                if (!CanonicalCodeDictionary.TryGetValue(status.CanonicalCode, out string statusCode))
                {
                    statusCode = status.CanonicalCode.ToString();
                    CanonicalCodeDictionary.Add(status.CanonicalCode, statusCode);
                }

                PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(StatusCode, JaegerTagType.STRING, vStr : statusCode));

                if (status.Description != null)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(StatusDescription, JaegerTagType.STRING, vStr : status.Description));
                }
            }

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

            if (span.Context.IsValid)
            {
                traceId      = new Int128(span.Context.TraceId);
                spanId       = new Int128(span.Context.SpanId);
                parentSpanId = new Int128(span.ParentSpanId);
            }

            return(new JaegerSpan(
                       peerServiceName: jaegerTags.PeerService,
                       traceIdLow: traceId.Low,
                       traceIdHigh: traceId.High,
                       spanId: spanId.Low,
                       parentSpanId: parentSpanId.Low,
                       operationName: span.Name,
                       flags: (span.Context.TraceOptions & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                       startTime: ToEpochMicroseconds(span.StartTimestamp),
                       duration: ToEpochMicroseconds(span.EndTimestamp) - ToEpochMicroseconds(span.StartTimestamp),
                       references: span.Links.ToJaegerSpanRefs(),
                       tags: jaegerTags.Tags,
                       logs: span.Events.ToJaegerLogs()));
        }
        private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000

        public static JaegerSpan ToJaegerSpan(this SpanData span)
        {
            var jaegerTags = span.Attributes?.Select(a => a.ToJaegerTag()).ToList() ?? new List <JaegerTag>();

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

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

                if (spanKind != null)
                {
                    jaegerTags.Add(new JaegerTag
                    {
                        Key   = "span.kind",
                        VType = JaegerTagType.STRING,
                        VStr  = spanKind,
                    });
                }
            }

            foreach (var label in span.LibraryResource?.Attributes ?? Array.Empty <KeyValuePair <string, object> >())
            {
                switch (label.Key)
                {
                case Resource.LibraryNameKey:
                    jaegerTags.Add(label.ToJaegerTag());
                    break;

                case Resource.LibraryVersionKey:
                    jaegerTags.Add(label.ToJaegerTag());
                    break;
                }
            }

            var status = span.Status;

            if (status.IsValid)
            {
                jaegerTags.Add(new JaegerTag
                {
                    Key   = StatusCode,
                    VType = JaegerTagType.STRING,
                    VStr  = status.CanonicalCode.ToString(),
                });

                if (status.Description != null)
                {
                    jaegerTags.Add(new JaegerTag
                    {
                        Key   = StatusDescription,
                        VType = JaegerTagType.STRING,
                        VStr  = status.Description,
                    });
                }
            }

            IEnumerable <JaegerLog> jaegerLogs = null;

            if (span.Events != null)
            {
                jaegerLogs = span.Events.Select(e => e.ToJaegerLog()).AsEnumerable();
            }

            IEnumerable <JaegerSpanRef> refs = null;

            if (span.Links != null)
            {
                refs = span.Links.Select(l => l.ToJaegerSpanRef()).Where(l => l != null).AsEnumerable();
            }

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

            if (span.Context.IsValid)
            {
                traceId      = new Int128(span.Context.TraceId);
                spanId       = new Int128(span.Context.SpanId);
                parentSpanId = new Int128(span.ParentSpanId);
            }

            return(new JaegerSpan
            {
                TraceIdHigh = traceId.High,
                TraceIdLow = traceId.Low,
                SpanId = spanId.Low,
                ParentSpanId = parentSpanId.Low,
                OperationName = span.Name,
                References = refs,
                Flags = (span.Context.TraceOptions & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                StartTime = ToEpochMicroseconds(span.StartTimestamp),
                Duration = ToEpochMicroseconds(span.EndTimestamp) - ToEpochMicroseconds(span.StartTimestamp),
                JaegerTags = jaegerTags,
                Logs = jaegerLogs,
            });
        }
        public static JaegerSpan ToJaegerSpan(this SpanData span)
        {
            var jaegerTags = PooledList <JaegerTag> .Create();

            Tuple <string, int> peerService = null;

            foreach (var label in span.Attributes)
            {
                var tag = label.ToJaegerTag();

                if (tag.VStr != null &&
                    PeerServiceKeyResolutionDictionary.TryGetValue(label.Key, out int priority) &&
                    (peerService == null || priority < peerService.Item2))
                {
                    peerService = new Tuple <string, int>(tag.VStr, priority);
                }

                PooledList <JaegerTag> .Add(ref jaegerTags, tag);
            }

            // Send peer.service for remote calls. If priority = 0 that means peer.service was already included.
            if ((span.Kind == SpanKind.Client || span.Kind == SpanKind.Producer) &&
                peerService != null &&
                peerService.Item2 > 0)
            {
                PooledList <JaegerTag> .Add(ref jaegerTags, new JaegerTag("peer.service", JaegerTagType.STRING, vStr : peerService.Item1));
            }

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

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

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

            foreach (var label in span.LibraryResource?.Attributes ?? Array.Empty <KeyValuePair <string, object> >())
            {
                switch (label.Key)
                {
                case Resource.LibraryNameKey:
                    PooledList <JaegerTag> .Add(ref jaegerTags, label.ToJaegerTag());

                    break;

                case Resource.LibraryVersionKey:
                    PooledList <JaegerTag> .Add(ref jaegerTags, label.ToJaegerTag());

                    break;
                }
            }

            var status = span.Status;

            if (status.IsValid)
            {
                if (!CanonicalCodeDictionary.TryGetValue(status.CanonicalCode, out string statusCode))
                {
                    statusCode = status.CanonicalCode.ToString();
                    CanonicalCodeDictionary.Add(status.CanonicalCode, statusCode);
                }

                PooledList <JaegerTag> .Add(ref jaegerTags, new JaegerTag(StatusCode, JaegerTagType.STRING, vStr : statusCode));

                if (status.Description != null)
                {
                    PooledList <JaegerTag> .Add(ref jaegerTags, new JaegerTag(StatusDescription, JaegerTagType.STRING, vStr : status.Description));
                }
            }

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

            if (span.Context.IsValid)
            {
                traceId      = new Int128(span.Context.TraceId);
                spanId       = new Int128(span.Context.SpanId);
                parentSpanId = new Int128(span.ParentSpanId);
            }

            return(new JaegerSpan(
                       peerServiceName: peerService?.Item1,
                       traceIdLow: traceId.Low,
                       traceIdHigh: traceId.High,
                       spanId: spanId.Low,
                       parentSpanId: parentSpanId.Low,
                       operationName: span.Name,
                       flags: (span.Context.TraceOptions & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                       startTime: ToEpochMicroseconds(span.StartTimestamp),
                       duration: ToEpochMicroseconds(span.EndTimestamp) - ToEpochMicroseconds(span.StartTimestamp),
                       references: span.Links.ToJaegerSpanRefs(),
                       tags: jaegerTags,
                       logs: span.Events.ToJaegerLogs()));
        }
        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()));
        }
Beispiel #14
0
        public static JaegerSpan ToJaegerSpan(this SpanData span)
        {
            var jaegerTags = new List <JaegerTag>();

            Tuple <string, int> peerService = null;

            foreach (var label in span.Attributes)
            {
                var tag = label.ToJaegerTag();

                if (tag.VStr != null &&
                    PeerServiceKeyResolutionDictionary.TryGetValue(label.Key, out int priority) &&
                    (peerService == null || priority < peerService.Item2))
                {
                    peerService = new Tuple <string, int>(tag.VStr, priority);
                }

                jaegerTags.Add(tag);
            }

            // Send peer.service for remote calls. If priority = 0 that means peer.service was already included.
            if ((span.Kind == SpanKind.Client || span.Kind == SpanKind.Producer) &&
                peerService != null &&
                peerService.Item2 > 0)
            {
                jaegerTags.Add(new JaegerTag
                {
                    Key   = "peer.service",
                    VType = JaegerTagType.STRING,
                    VStr  = peerService.Item1,
                });
            }

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

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

                if (spanKind != null)
                {
                    jaegerTags.Add(new JaegerTag
                    {
                        Key   = "span.kind",
                        VType = JaegerTagType.STRING,
                        VStr  = spanKind,
                    });
                }
            }

            foreach (var label in span.LibraryResource?.Attributes ?? Array.Empty <KeyValuePair <string, object> >())
            {
                switch (label.Key)
                {
                case Resource.LibraryNameKey:
                    jaegerTags.Add(label.ToJaegerTag());
                    break;

                case Resource.LibraryVersionKey:
                    jaegerTags.Add(label.ToJaegerTag());
                    break;
                }
            }

            var status = span.Status;

            if (status.IsValid)
            {
                jaegerTags.Add(new JaegerTag
                {
                    Key   = StatusCode,
                    VType = JaegerTagType.STRING,
                    VStr  = status.CanonicalCode.ToString(),
                });

                if (status.Description != null)
                {
                    jaegerTags.Add(new JaegerTag
                    {
                        Key   = StatusDescription,
                        VType = JaegerTagType.STRING,
                        VStr  = status.Description,
                    });
                }
            }

            IEnumerable <JaegerLog> jaegerLogs = null;

            if (span.Events != null)
            {
                jaegerLogs = span.Events.Select(e => e.ToJaegerLog()).AsEnumerable();
            }

            IEnumerable <JaegerSpanRef> refs = null;

            if (span.Links != null)
            {
                refs = span.Links.Select(l => l.ToJaegerSpanRef()).Where(l => l != null).AsEnumerable();
            }

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

            if (span.Context.IsValid)
            {
                traceId      = new Int128(span.Context.TraceId);
                spanId       = new Int128(span.Context.SpanId);
                parentSpanId = new Int128(span.ParentSpanId);
            }

            return(new JaegerSpan
            {
                TraceIdHigh = traceId.High,
                TraceIdLow = traceId.Low,
                SpanId = spanId.Low,
                ParentSpanId = parentSpanId.Low,
                OperationName = span.Name,
                References = refs,
                Flags = (span.Context.TraceOptions & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
                StartTime = ToEpochMicroseconds(span.StartTimestamp),
                Duration = ToEpochMicroseconds(span.EndTimestamp) - ToEpochMicroseconds(span.StartTimestamp),
                JaegerTags = jaegerTags,
                Logs = jaegerLogs,
            });
        }