Beispiel #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZipkinTraceExporter"/> class.
 /// </summary>
 /// <param name="options">Configuration options.</param>
 /// <param name="client">Http client to use to upload telemetry.</param>
 public ZipkinTraceExporter(ZipkinTraceExporterOptions options, HttpClient client = null)
 {
     this.options         = options;
     this.localEndpoint   = this.GetLocalZipkinEndpoint();
     this.httpClient      = client ?? new HttpClient();
     this.serviceEndpoint = options.Endpoint?.ToString();
 }
Beispiel #2
0
        public void GenerateSpan()
        {
            ZipkinEndpoint localEndpoint = new ZipkinEndpoint()
            {
                ServiceName = "tweetiebird"
            };

            var traceId  = "d239036e7d5cec116b562147388b35bf";
            var spanId   = "9cc1e3049173be09";
            var parentId = "8b03ab423da481c5";

            Dictionary <string, IAttributeValue> attributes    = new Dictionary <string, IAttributeValue>();
            IList <ITimedEvent <IAnnotation> >   annotations   = new List <ITimedEvent <IAnnotation> >();
            List <ITimedEvent <IMessageEvent> >  networkEvents = new List <ITimedEvent <IMessageEvent> >()
            {
                TimedEvent <IMessageEvent> .Create(Timestamp.Create(EPOCH_SECONDS + 1505855799, 433901068), new MessageEventBuilder(MessageEventType.RECEIVED, 0, 0, 0).SetCompressedMessageSize(7).Build()),
                TimedEvent <IMessageEvent> .Create(Timestamp.Create(EPOCH_SECONDS + 1505855799, 459486280), new MessageEventBuilder(MessageEventType.SENT, 0, 0, 0).SetCompressedMessageSize(13).Build())
            };

            ISpanData data = SpanData.Create(
                SpanContext.Create(
                    TraceId.FromBytes(Arrays.StringToByteArray(traceId)),
                    SpanId.FromBytes(Arrays.StringToByteArray(spanId)),
                    TraceOptions.FromBytes(new byte[] { 1 })),
                SpanId.FromBytes(Arrays.StringToByteArray(parentId)),
                true,                               /* hasRemoteParent */
                "Recv.helloworld.Greeter.SayHello", /* name */
                Timestamp.Create(EPOCH_SECONDS + 1505855794, 194009601) /* startTimestamp */,
                Attributes.Create(attributes, 0 /* droppedAttributesCount */),
                TimedEvents <IAnnotation> .Create(annotations, 0 /* droppedEventsCount */),
                TimedEvents <IMessageEvent> .Create(networkEvents, 0 /* droppedEventsCount */),
                LinkList.Create(new List <ILink>(), 0 /* droppedLinksCount */),
                null, /* childSpanCount */
                Status.OK,
                Timestamp.Create(EPOCH_SECONDS + 1505855799, 465726528) /* endTimestamp */);

            var handler = new TraceExporterHandler(new TraceExporterOptions()
            {
                UseShortTraceIds = false
            });
            var result = handler.GenerateSpan(data, localEndpoint);

            var zspan = ZipkinSpan.NewBuilder()
                        .TraceId(traceId)
                        .ParentId(parentId)
                        .Id(spanId)
                        .Kind(ZipkinSpanKind.SERVER)
                        .Name(data.Name)
                        .Timestamp(1505855794000000L + (194009601L / 1000))
                        .Duration(
                (1505855799000000L + (465726528L / 1000))
                - (1505855794000000L + (194009601L / 1000)))
                        .LocalEndpoint(localEndpoint)
                        .AddAnnotation(1505855799000000L + (433901068L / 1000), "RECEIVED")
                        .AddAnnotation(1505855799000000L + (459486280L / 1000), "SENT")
                        .PutTag("census.status_code", "OK")
                        .Build();

            Assert.Equal(zspan, result);
        }
        internal ZipkinSpan GenerateSpan(Span otelSpan, ZipkinEndpoint localEndpoint)
        {
            var context        = otelSpan.Context;
            var startTimestamp = this.ToEpochMicroseconds(otelSpan.StartTimestamp);
            var endTimestamp   = this.ToEpochMicroseconds(otelSpan.EndTimestamp);

            var spanBuilder =
                ZipkinSpan.NewBuilder()
                .ActivityTraceId(this.EncodeTraceId(context.TraceId))
                .Id(this.EncodeSpanId(context.SpanId))
                .Kind(this.ToSpanKind(otelSpan))
                .Name(otelSpan.Name)
                .Timestamp(this.ToEpochMicroseconds(otelSpan.StartTimestamp))
                .Duration(endTimestamp - startTimestamp)
                .LocalEndpoint(localEndpoint);

            if (otelSpan.ParentSpanId != default)
            {
                spanBuilder.ParentId(this.EncodeSpanId(otelSpan.ParentSpanId));
            }

            foreach (var label in otelSpan.Attributes)
            {
                spanBuilder.PutTag(label.Key, label.Value.ToString());
            }

            var status = otelSpan.Status;

            if (status.IsValid)
            {
                spanBuilder.PutTag(StatusCode, status.CanonicalCode.ToString());

                if (status.Description != null)
                {
                    spanBuilder.PutTag(StatusDescription, status.Description);
                }
            }

            foreach (var annotation in otelSpan.Events)
            {
                spanBuilder.AddAnnotation(this.ToEpochMicroseconds(annotation.Timestamp), annotation.Name);
            }

            return(spanBuilder.Build());
        }
Beispiel #4
0
        private ZipkinEndpoint GetLocalZipkinEndpoint()
        {
            var result = new ZipkinEndpoint()
            {
                ServiceName = this.options.ServiceName,
            };

            var hostName = this.ResolveHostName();

            if (!string.IsNullOrEmpty(hostName))
            {
                result.Ipv4 = this.ResolveHostAddress(hostName, AddressFamily.InterNetwork);

                result.Ipv6 = this.ResolveHostAddress(hostName, AddressFamily.InterNetworkV6);
            }

            return(result);
        }
Beispiel #5
0
        internal ZipkinSpan GenerateSpan(Span otelSpan, ZipkinEndpoint defaultLocalEndpoint)
        {
            var context        = otelSpan.Context;
            var startTimestamp = this.ToEpochMicroseconds(otelSpan.StartTimestamp);
            var endTimestamp   = this.ToEpochMicroseconds(otelSpan.EndTimestamp);

            var spanBuilder =
                ZipkinSpan.NewBuilder()
                .TraceId(this.EncodeTraceId(context.TraceId))
                .Id(this.EncodeSpanId(context.SpanId))
                .Kind(this.ToSpanKind(otelSpan))
                .Name(otelSpan.Name)
                .Timestamp(this.ToEpochMicroseconds(otelSpan.StartTimestamp))
                .Duration(endTimestamp - startTimestamp);

            if (otelSpan.ParentSpanId != default)
            {
                spanBuilder.ParentId(this.EncodeSpanId(otelSpan.ParentSpanId));
            }

            foreach (var label in otelSpan.Attributes)
            {
                spanBuilder.PutTag(label.Key, label.Value.ToString());
            }

            // See https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-resource-semantic-conventions.md
            string serviceName      = string.Empty;
            string serviceNamespace = string.Empty;

            foreach (var label in otelSpan.LibraryResource.Attributes)
            {
                string key = label.Key;
                string val = label.Value;

                if (key == "service.name")
                {
                    serviceName = val;
                }
                else if (key == "service.namespace")
                {
                    serviceNamespace = val;
                }
                else
                {
                    spanBuilder.PutTag(key, val);
                }
            }

            if (serviceNamespace != string.Empty)
            {
                serviceName = serviceNamespace + "." + serviceName;
            }

            var endpoint = defaultLocalEndpoint;

            // override default service name
            // TODO: add caching
            if (serviceName != string.Empty)
            {
                endpoint = new ZipkinEndpoint()
                {
                    Ipv4        = defaultLocalEndpoint.Ipv4,
                    Ipv6        = defaultLocalEndpoint.Ipv6,
                    Port        = defaultLocalEndpoint.Port,
                    ServiceName = serviceName,
                };
            }

            spanBuilder.LocalEndpoint(endpoint);

            var status = otelSpan.Status;

            if (status.IsValid)
            {
                spanBuilder.PutTag(StatusCode, status.CanonicalCode.ToString());

                if (status.Description != null)
                {
                    spanBuilder.PutTag(StatusDescription, status.Description);
                }
            }

            foreach (var annotation in otelSpan.Events)
            {
                spanBuilder.AddAnnotation(this.ToEpochMicroseconds(annotation.Timestamp), annotation.Name);
            }

            return(spanBuilder.Build());
        }