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()); }
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()); }