/// <summary> /// Returns a new immutable <see cref="SpanData"/>. /// </summary> /// <param name="context">The <see cref="SpanContext"/> of the <see cref="ISpan"/>.</param> /// <param name="parentSpanId">The parent <see cref="SpanId"/> of the <see cref="ISpan"/>. <c>null</c> if the <see cref="ISpan"/> is a root.</param> /// <param name="resource">The <see cref="Resource"/> this span was executed on.</param> /// <param name="name">The name of the <see cref="ISpan"/>.</param> /// <param name="startTimestamp">The start <see cref="Timestamp"/> of the <see cref="ISpan"/>.</param> /// <param name="attributes">The <see cref="IAttributes"/> associated with the <see cref="ISpan"/>.</param> /// <param name="events">The <see cref="Events"/> associated with the <see cref="ISpan"/>.</param> /// <param name="links">The <see cref="ILinks"/> associated with the <see cref="ISpan"/>.</param> /// <param name="childSpanCount">The <see cref="ChildSpanCount"/> associated with the <see cref="ISpan"/>.</param> /// <param name="status">The <see cref="Status"/> of the <see cref="ISpan"/>.</param> /// <param name="kind">The <see cref="SpanKind"/> of the <see cref="ISpan"/>.</param> /// <param name="endTimestamp">The end <see cref="Timestamp"/> of the <see cref="ISpan"/>.</param> /// <returns>A new immutable <see cref="SpanData"/>.</returns> public static SpanData Create( SpanContext context, SpanId parentSpanId, Resource resource, string name, Timestamp startTimestamp, IAttributes attributes, ITimedEvents <IEvent> events, ILinks links, int?childSpanCount, Status status, SpanKind kind, Timestamp endTimestamp) { if (events == null) { events = TimedEvents <IEvent> .Create(new List <ITimedEvent <IEvent> >(), 0); } return(new SpanData( context, parentSpanId, resource, name, startTimestamp, attributes, events, links, childSpanCount, status, kind, endTimestamp)); }
internal SpanData( SpanContext context, SpanId parentSpanId, Resource resource, string name, Timestamp startTimestamp, IAttributes attributes, ITimedEvents <IEvent> events, ILinks links, int?childSpanCount, Status status, SpanKind kind, Timestamp endTimestamp) { this.Context = context ?? throw new ArgumentNullException(nameof(context)); this.ParentSpanId = parentSpanId; this.Resource = resource ?? throw new ArgumentNullException(nameof(resource)); this.Name = name ?? throw new ArgumentNullException(nameof(name)); this.StartTimestamp = startTimestamp ?? throw new ArgumentNullException(nameof(startTimestamp)); this.Attributes = attributes ?? Export.Attributes.Create(new Dictionary <string, IAttributeValue>(), 0); this.Events = events ?? TimedEvents <IEvent> .Create(Enumerable.Empty <ITimedEvent <IEvent> >(), 0); this.Links = links ?? LinkList.Create(Enumerable.Empty <ILink>(), 0); this.ChildSpanCount = childSpanCount; this.Status = status; this.Kind = kind; this.EndTimestamp = endTimestamp; }
public SpanData ToSpanData() { if (!this.IsRecordingEvents) { throw new InvalidOperationException("Getting SpanData for a Span without RECORD_EVENTS option."); } var attributesSpanData = Attributes.Create(this.attributes?.ToReadOnlyCollection(), this.attributes?.DroppedItems ?? 0); var eventsSpanData = TimedEvents <IEvent> .Create(this.events?.ToReadOnlyCollection(), this.events?.DroppedItems ?? 0); var linksSpanData = LinkList.Create(this.links?.ToReadOnlyCollection(), this.links?.DroppedItems ?? 0); return(SpanData.Create( this.Context, // TODO avoid using context, use Activity instead this.ParentSpanId, Resource.Empty, // TODO: determine what to do with Resource in this context this.Name, this.Activity.StartTimeUtc, attributesSpanData, eventsSpanData, linksSpanData, null, // Not supported yet. this.HasEnded ? this.StatusWithDefault : new Status(), this.Kind ?? SpanKind.Internal, this.HasEnded ? (this.Activity.StartTimeUtc + this.Activity.Duration) : default)); }
public void SpanData_AllDataEmpty() { ISpanData spanData = SpanData.Create( spanContext, parentSpanId, false, SPAN_NAME, startTimestamp, Attributes.Create(new Dictionary <string, IAttributeValue>(), 0), TimedEvents <IEvent> .Create(new List <ITimedEvent <IEvent> >(), 0), LinkList.Create(new List <ILink>(), 0), 0, status, kind, endTimestamp); Assert.Equal(spanContext, spanData.Context); Assert.Equal(parentSpanId, spanData.ParentSpanId); Assert.False(spanData.HasRemoteParent); Assert.Equal(SPAN_NAME, spanData.Name); Assert.Equal(startTimestamp, spanData.StartTimestamp); Assert.Empty(spanData.Attributes.AttributeMap); Assert.Empty(spanData.Events.Events); Assert.Empty(spanData.Links.Links); Assert.Equal(0, spanData.ChildSpanCount); Assert.Equal(status, spanData.Status); Assert.Equal(endTimestamp, spanData.EndTimestamp); }
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); }
public void SpanDataEquals() { ISpanData allSpanData1 = SpanData.Create( spanContext, parentSpanId, false, SPAN_NAME, startTimestamp, attributes, annotations, messageEvents, links, CHILD_SPAN_COUNT, status, kind, endTimestamp); ISpanData allSpanData2 = SpanData.Create( spanContext, parentSpanId, false, SPAN_NAME, startTimestamp, attributes, annotations, messageEvents, links, CHILD_SPAN_COUNT, status, kind, endTimestamp); ISpanData emptySpanData = SpanData.Create( spanContext, parentSpanId, false, SPAN_NAME, startTimestamp, Attributes.Create(new Dictionary <string, IAttributeValue>(), 0), TimedEvents <IAnnotation> .Create(new List <ITimedEvent <IAnnotation> >(), 0), TimedEvents <IMessageEvent> .Create(new List <ITimedEvent <IMessageEvent> >(), 0), LinkList.Create(new List <ILink>(), 0), 0, status, kind, endTimestamp); Assert.Equal(allSpanData1, allSpanData2); Assert.NotEqual(emptySpanData, allSpanData1); Assert.NotEqual(emptySpanData, allSpanData2); }
public void SpanDataEquals() { var allSpanData1 = SpanData.Create( spanContext, parentSpanId, resource, SPAN_NAME, startTimestamp, attributes, events, links, CHILD_SPAN_COUNT, status, SPAN_KIND, endTimestamp); var allSpanData2 = SpanData.Create( spanContext, parentSpanId, resource, SPAN_NAME, startTimestamp, attributes, events, links, CHILD_SPAN_COUNT, status, SPAN_KIND, endTimestamp); var emptySpanData = SpanData.Create( spanContext, parentSpanId, resource, SPAN_NAME, startTimestamp, Attributes.Create(new Dictionary <string, IAttributeValue>(), 0), TimedEvents <IEvent> .Create(new List <ITimedEvent <IEvent> >(), 0), LinkList.Create(new List <ILink>(), 0), 0, status, SPAN_KIND, endTimestamp); Assert.Equal(allSpanData1, allSpanData2); Assert.NotEqual(emptySpanData, allSpanData1); Assert.NotEqual(emptySpanData, allSpanData2); }
private static ITimedEvents <T> CreateTimedEvents <T>(TraceEvents <EventWithNanoTime <T> > events, ITimestampConverter timestampConverter) { if (events == null) { IList <ITimedEvent <T> > empty = new List <ITimedEvent <T> >(); return(TimedEvents <T> .Create(empty, 0)); } IList <ITimedEvent <T> > eventsList = new List <ITimedEvent <T> >(events.Events.Count); foreach (EventWithNanoTime <T> networkEvent in events.Events) { eventsList.Add(networkEvent.ToSpanDataTimedEvent(timestampConverter)); } return(TimedEvents <T> .Create(eventsList, events.NumberOfDroppedEvents)); }
public SpanDataTest() { spanContext = SpanContext.Create(TraceId.GenerateRandomId(random), SpanId.GenerateRandomId(random), TraceOptions.Default, Tracestate.Empty); parentSpanId = SpanId.GenerateRandomId(random); attributesMap.Add("MyAttributeKey1", AttributeValue.LongAttributeValue(10)); attributesMap.Add("MyAttributeKey2", AttributeValue.BooleanAttributeValue(true)); attributes = Attributes.Create(attributesMap, 1); eventList.Add(TimedEvent <IEvent> .Create(eventTimestamp1, spanEvent)); eventList.Add(TimedEvent <IEvent> .Create(eventTimestamp3, spanEvent)); events = TimedEvents <IEvent> .Create(eventList, 2); linksList.Add(Link.FromSpanContext(spanContext, LinkType.ChildLinkedSpan)); links = LinkList.Create(linksList, 0); }
public SpanDataTest() { spanContext = SpanContext.Create(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None, Tracestate.Empty); parentSpanId = ActivitySpanId.CreateRandom(); attributesMap.Add("MyAttributeKey1", 10L); attributesMap.Add("MyAttributeKey2", true); attributes = Attributes.Create(new ReadOnlyDictionary <string, object>(attributesMap), 1); eventList.Add(TimedEvent <IEvent> .Create(eventTimestamp1, spanEvent)); eventList.Add(TimedEvent <IEvent> .Create(eventTimestamp3, spanEvent)); events = TimedEvents <IEvent> .Create(eventList, 2); linksList.Add(Link.FromSpanContext(spanContext)); links = LinkList.Create(linksList, 0); }
private static ITimedEvents <T> CreateTimedEvents <T>(TraceEvents <EventWithTime <T> > events, Timer timestampConverter) { if (events == null) { IEnumerable <ITimedEvent <T> > empty = Array.Empty <ITimedEvent <T> >(); return(TimedEvents <T> .Create(empty, 0)); } var eventsList = new List <ITimedEvent <T> >(events.Events.Count); foreach (var networkEvent in events.Events) { eventsList.Add(networkEvent.ToSpanDataTimedEvent(timestampConverter)); } return(TimedEvents <T> .Create(eventsList, events.NumberOfDroppedEvents)); }
public SpanDataTest() { spanContext = SpanContext.Create(TraceId.GenerateRandomId(random), SpanId.GenerateRandomId(random), TraceOptions.DEFAULT); parentSpanId = SpanId.GenerateRandomId(random); attributesMap.Add("MyAttributeKey1", AttributeValue.LongAttributeValue(10)); attributesMap.Add("MyAttributeKey2", AttributeValue.BooleanAttributeValue(true)); attributes = Attributes.Create(attributesMap, 1); annotationsList.Add(TimedEvent <IAnnotation> .Create(eventTimestamp1, annotation)); annotationsList.Add(TimedEvent <IAnnotation> .Create(eventTimestamp3, annotation)); annotations = TimedEvents <IAnnotation> .Create(annotationsList, 2); //networkEventsList.add(SpanData.TimedEvent.Create(eventTimestamp1, recvNetworkEvent)); //networkEventsList.add(SpanData.TimedEvent.Create(eventTimestamp2, sentNetworkEvent)); //networkEvents = TimedEvents.Create(networkEventsList, 3); messageEventsList.Add(TimedEvent <IMessageEvent> .Create(eventTimestamp1, recvMessageEvent)); messageEventsList.Add(TimedEvent <IMessageEvent> .Create(eventTimestamp2, sentMessageEvent)); messageEvents = TimedEvents <IMessageEvent> .Create(messageEventsList, 3); linksList.Add(Link.FromSpanContext(spanContext, LinkType.CHILD_LINKED_SPAN)); links = LinkList.Create(linksList, 0); }
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_NoAttributes() { var startTimestamp = DateTime.Now; var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = DateTime.Now; var traceId = ActivityTraceId.CreateRandom(); var traceIdAsInt = new Int128(traceId); var spanId = ActivitySpanId.CreateRandom(); var spanIdAsInt = new Int128(spanId); var parentSpanId = ActivitySpanId.CreateRandom(); var events = TimedEvents <IEvent> .Create(new List <ITimedEvent <IEvent> > { TimedEvent <IEvent> .Create( eventTimestamp, Event.Create( "Event1", new Dictionary <string, object> { { "key", "value" }, } ) ), TimedEvent <IEvent> .Create( eventTimestamp, Event.Create( "Event2", new Dictionary <string, object> { { "key", "value" }, } ) ), }, 0); var linkedSpanId = ActivitySpanId.CreateRandom(); var link = Link.FromSpanContext(SpanContext.Create( traceId, linkedSpanId, ActivityTraceFlags.Recorded, Tracestate.Empty)); var linkTraceIdAsInt = new Int128(link.Context.TraceId); var linkSpanIdAsInt = new Int128(link.Context.SpanId); var links = LinkList.Create(new List <ILink> { link }, 0); var spanData = SpanData.Create( SpanContext.Create( traceId, spanId, ActivityTraceFlags.Recorded, Tracestate.Empty ), parentSpanId, Resource.Empty, "Name", startTimestamp, null, events, links, null, Status.Ok, SpanKind.Client, endTimestamp ); var jaegerSpan = spanData.ToJaegerSpan(); Assert.Equal("Name", jaegerSpan.OperationName); Assert.Equal(2, jaegerSpan.Logs.Count()); Assert.Equal(traceIdAsInt.High, jaegerSpan.TraceIdHigh); Assert.Equal(traceIdAsInt.Low, jaegerSpan.TraceIdLow); Assert.Equal(spanIdAsInt.Low, jaegerSpan.SpanId); Assert.Equal(new Int128(parentSpanId).Low, jaegerSpan.ParentSpanId); Assert.Equal(links.Links.Count(), jaegerSpan.References.Count()); var references = jaegerSpan.References.ToArray(); var jaegerRef = references[0]; Assert.Equal(linkTraceIdAsInt.High, jaegerRef.TraceIdHigh); Assert.Equal(linkTraceIdAsInt.Low, jaegerRef.TraceIdLow); Assert.Equal(linkSpanIdAsInt.Low, jaegerRef.SpanId); Assert.Equal(0x1, jaegerSpan.Flags); Assert.Equal(startTimestamp.ToEpochMicroseconds(), jaegerSpan.StartTime); Assert.Equal(endTimestamp.ToEpochMicroseconds() - startTimestamp.ToEpochMicroseconds(), jaegerSpan.Duration); Assert.Empty(jaegerSpan.JaegerTags); var logs = jaegerSpan.Logs.ToArray(); var jaegerLog = logs[0]; Assert.Equal(events.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp); Assert.Equal(jaegerLog.Fields.Count(), 2); var eventFields = jaegerLog.Fields.ToArray(); var eventField = eventFields[0]; Assert.Equal("key", eventField.Key); Assert.Equal("value", eventField.VStr); eventField = eventFields[1]; Assert.Equal("description", eventField.Key); Assert.Equal("Event1", eventField.VStr); jaegerLog = logs[1]; Assert.Equal(events.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp); Assert.Equal(jaegerLog.Fields.Count(), 2); eventFields = jaegerLog.Fields.ToArray(); eventField = eventFields[0]; Assert.Equal("key", eventField.Key); Assert.Equal("value", eventField.VStr); eventField = eventFields[1]; Assert.Equal("description", eventField.Key); Assert.Equal("Event2", eventField.VStr); }
internal static ISpanData ProfiledCommandToSpanData(ISpanContext context, string name, ISpanId parentSpanId, IProfiledCommand command) { var hasRemoteParent = false; // use https://github.com/opentracing/specification/blob/master/semantic_conventions.md for now // Timing example: // command.CommandCreated; //2019-01-10 22:18:28Z // command.CreationToEnqueued; // 00:00:32.4571995 // command.EnqueuedToSending; // 00:00:00.0352838 // command.SentToResponse; // 00:00:00.0060586 // command.ResponseToCompletion; // 00:00:00.0002601 // Total: // command.ElapsedTime; // 00:00:32.4988020 // TODO: make timestamp with the better precision Timestamp startTimestamp = Timestamp.FromMillis(new DateTimeOffset(command.CommandCreated).ToUnixTimeMilliseconds()); var timestamp = new DateTimeOffset(command.CommandCreated).Add(command.CreationToEnqueued); var events = TimedEvents <IEvent> .Create( new List <ITimedEvent <IEvent> >() { TimedEvent <IEvent> .Create(Timestamp.FromMillis(timestamp.ToUnixTimeMilliseconds()), Event.Create("Enqueued")), TimedEvent <IEvent> .Create(Timestamp.FromMillis((timestamp = timestamp.Add(command.EnqueuedToSending)).ToUnixTimeMilliseconds()), Event.Create("Sent")), TimedEvent <IEvent> .Create(Timestamp.FromMillis((timestamp = timestamp.Add(command.SentToResponse)).ToUnixTimeMilliseconds()), Event.Create("ResponseRecieved")), }, droppedEventsCount : 0); Timestamp endTimestamp = Timestamp.FromMillis(new DateTimeOffset(command.CommandCreated.Add(command.ElapsedTime)).ToUnixTimeMilliseconds()); // TODO: deal with the re-transmission // command.RetransmissionOf; // command.RetransmissionReason; var attributesMap = new Dictionary <string, IAttributeValue>() { // TODO: pre-allocate constant attribute and reuse { "db.type", AttributeValue.StringAttributeValue("redis") }, // Example: "redis.flags": None, DemandMaster { "redis.flags", AttributeValue.StringAttributeValue(command.Flags.ToString()) }, }; if (command.Command != null) { // Example: "db.statement": SET; attributesMap.Add("db.statement", AttributeValue.StringAttributeValue(command.Command)); } if (command.EndPoint != null) { // Example: "db.instance": Unspecified/localhost:6379[0] attributesMap.Add("db.instance", AttributeValue.StringAttributeValue(command.EndPoint.ToString() + "[" + command.Db + "]")); } var attributes = Attributes.Create(attributesMap, 0); ILinks links = null; int? childSpanCount = 0; // TODO: this is strange that IProfiledCommand doesn't give the result Status status = Status.Ok; SpanKind kind = SpanKind.Client; return(SpanData.Create(context, parentSpanId, hasRemoteParent, name, startTimestamp, attributes, events, links, childSpanCount, status, kind, endTimestamp)); }
public void AllPropertiesShouldTranslate() { var startTs = DateTime.Now; var endTs = startTs.AddSeconds(60); var evtTs = DateTime.Now; var traceId = ActivityTraceId.CreateRandom(); var spanId = ActivitySpanId.CreateRandom(); var parentId = ActivitySpanId.CreateRandom(); var traceIdInt = traceId.ToLSTraceId(); var spanIdInt = spanId.ToLSSpanId(); var parentIdInt = parentId.ToLSSpanId(); var attrs = Attributes.Create(new Dictionary <string, object> { { "stringKey", "foo" }, { "longKey", 1L }, { "doubleKey", 1D }, { "boolKey", true }, }, 0); var evts = TimedEvents <IEvent> .Create(new List <ITimedEvent <IEvent> > { TimedEvent <IEvent> .Create( evtTs, Event.Create( "evt1", new Dictionary <string, object> { { "key", "value" }, } ) ), TimedEvent <IEvent> .Create( evtTs, Event.Create( "evt2", new Dictionary <string, object> { { "key", "value" }, } ) ), }, 0); var linkedSpanId = ActivitySpanId.CreateRandom(); var link = Link.FromSpanContext(SpanContext.Create( traceId, linkedSpanId, ActivityTraceFlags.Recorded, Tracestate.Empty)); var links = LinkList.Create(new List <ILink> { link }, 0); var spanData = SpanData.Create( SpanContext.Create( traceId, spanId, ActivityTraceFlags.Recorded, Tracestate.Empty ), parentId, Resource.Empty, "Test", startTs, attrs, evts, links, null, Status.Ok, SpanKind.Client, endTs ); var lsSpan = spanData.ToLightStepSpan(); Assert.Equal("Test", lsSpan.OperationName); Assert.Equal(2, lsSpan.Logs.Count); Assert.Equal(4, lsSpan.Tags.Count); Assert.Equal(traceIdInt, lsSpan.SpanContext.TraceId); Assert.Equal(spanIdInt, lsSpan.SpanContext.SpanId); Assert.Equal(parentIdInt, lsSpan.References[0].SpanContext.SpanId); }
private SpanData CreateTestSpan() { var startTimestamp = new DateTime(2019, 1, 1); var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = new DateTime(2019, 1, 1); var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); var traceIdAsInt = new Int128(traceId); var spanId = ActivitySpanId.CreateFromString("6a69db47429ea340".AsSpan()); var spanIdAsInt = new Int128(spanId); var parentSpanId = ActivitySpanId.CreateFromBytes(new byte [] { 12, 23, 34, 45, 56, 67, 78, 89 }); var attributes = Attributes.Create(new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, }, 0); var events = TimedEvents <IEvent> .Create(new List <ITimedEvent <IEvent> > { TimedEvent <IEvent> .Create( eventTimestamp, Event.Create( "Event1", new Dictionary <string, object> { { "key", "value" }, } ) ), TimedEvent <IEvent> .Create( eventTimestamp, Event.Create( "Event2", new Dictionary <string, object> { { "key", "value" }, } ) ), }, 0); var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); var link = Link.FromSpanContext(SpanContext.Create( traceId, linkedSpanId, ActivityTraceFlags.Recorded, Tracestate.Empty)); var linkTraceIdAsInt = new Int128(link.Context.TraceId); var linkSpanIdAsInt = new Int128(link.Context.SpanId); var links = LinkList.Create(new List <ILink> { link }, 0); return(SpanData.Create( SpanContext.Create( traceId, spanId, ActivityTraceFlags.Recorded, Tracestate.Empty ), parentSpanId, Resource.Empty, "Name", startTimestamp, attributes, events, links, null, Status.Ok, SpanKind.Client, endTimestamp )); }
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_NoLinks() { var startTimestamp = DateTime.Now; var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = DateTime.Now; var traceId = ActivityTraceId.CreateRandom(); var traceIdAsInt = new Int128(traceId); var spanId = ActivitySpanId.CreateRandom(); var spanIdAsInt = new Int128(spanId); var parentSpanId = ActivitySpanId.CreateRandom(); var attributes = Attributes.Create(new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, }, 0); var events = TimedEvents <IEvent> .Create(new List <ITimedEvent <IEvent> > { TimedEvent <IEvent> .Create( eventTimestamp, Event.Create( "Event1", new Dictionary <string, object> { { "key", "value" }, } ) ), TimedEvent <IEvent> .Create( eventTimestamp, Event.Create( "Event2", new Dictionary <string, object> { { "key", "value" }, } ) ), }, 0); var spanData = SpanData.Create( SpanContext.Create( traceId, spanId, ActivityTraceFlags.Recorded, Tracestate.Empty ), parentSpanId, Resource.Empty, "Name", startTimestamp, attributes, events, null, null, Status.Ok, SpanKind.Client, endTimestamp ); var jaegerSpan = spanData.ToJaegerSpan(); Assert.Equal("Name", jaegerSpan.OperationName); Assert.Equal(2, jaegerSpan.Logs.Count()); Assert.Equal(traceIdAsInt.High, jaegerSpan.TraceIdHigh); Assert.Equal(traceIdAsInt.Low, jaegerSpan.TraceIdLow); Assert.Equal(spanIdAsInt.Low, jaegerSpan.SpanId); Assert.Equal(new Int128(parentSpanId).Low, jaegerSpan.ParentSpanId); Assert.Empty(jaegerSpan.References); Assert.Equal(0x1, jaegerSpan.Flags); Assert.Equal(startTimestamp.ToEpochMicroseconds(), jaegerSpan.StartTime); Assert.Equal(endTimestamp.ToEpochMicroseconds() - startTimestamp.ToEpochMicroseconds(), jaegerSpan.Duration); var tags = jaegerSpan.JaegerTags.ToArray(); var tag = tags[0]; Assert.Equal(JaegerTagType.STRING, tag.VType); Assert.Equal("stringKey", tag.Key); Assert.Equal("value", tag.VStr); tag = tags[1]; Assert.Equal(JaegerTagType.LONG, tag.VType); Assert.Equal("longKey", tag.Key); Assert.Equal(1, tag.VLong); tag = tags[2]; Assert.Equal(JaegerTagType.LONG, tag.VType); Assert.Equal("longKey2", tag.Key); Assert.Equal(1, tag.VLong); tag = tags[3]; Assert.Equal(JaegerTagType.DOUBLE, tag.VType); Assert.Equal("doubleKey", tag.Key); Assert.Equal(1, tag.VDouble); tag = tags[4]; Assert.Equal(JaegerTagType.DOUBLE, tag.VType); Assert.Equal("doubleKey2", tag.Key); Assert.Equal(1, tag.VDouble); tag = tags[5]; Assert.Equal(JaegerTagType.BOOL, tag.VType); Assert.Equal("boolKey", tag.Key); Assert.Equal(true, tag.VBool); var logs = jaegerSpan.Logs.ToArray(); var jaegerLog = logs[0]; Assert.Equal(events.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp); Assert.Equal(2, jaegerLog.Fields.Count()); var eventFields = jaegerLog.Fields.ToArray(); var eventField = eventFields[0]; Assert.Equal("key", eventField.Key); Assert.Equal("value", eventField.VStr); eventField = eventFields[1]; Assert.Equal("description", eventField.Key); Assert.Equal("Event1", eventField.VStr); jaegerLog = logs[1]; Assert.Equal(events.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp); Assert.Equal(jaegerLog.Fields.Count(), 2); eventFields = jaegerLog.Fields.ToArray(); eventField = eventFields[0]; Assert.Equal("key", eventField.Key); Assert.Equal("value", eventField.VStr); eventField = eventFields[1]; Assert.Equal("description", eventField.Key); Assert.Equal("Event2", eventField.VStr); }
internal static SpanData ProfiledCommandToSpanData(SpanContext context, string name, ActivitySpanId parentSpanId, IProfiledCommand command) { // use https://github.com/opentracing/specification/blob/master/semantic_conventions.md for now // Timing example: // command.CommandCreated; //2019-01-10 22:18:28Z // command.CreationToEnqueued; // 00:00:32.4571995 // command.EnqueuedToSending; // 00:00:00.0352838 // command.SentToResponse; // 00:00:00.0060586 // command.ResponseToCompletion; // 00:00:00.0002601 // Total: // command.ElapsedTime; // 00:00:32.4988020 // TODO: make timestamp with the better precision var startTimestamp = command.CommandCreated; var enqueued = command.CommandCreated.Add(command.CreationToEnqueued); var send = enqueued.Add(command.EnqueuedToSending); var response = send.Add(command.SentToResponse); var events = TimedEvents <IEvent> .Create( new List <ITimedEvent <IEvent> >() { TimedEvent <IEvent> .Create(enqueued, Event.Create("Enqueued")), TimedEvent <IEvent> .Create(send, Event.Create("Sent")), TimedEvent <IEvent> .Create(response, Event.Create("ResponseReceived")), }, droppedEventsCount : 0); var endTimestamp = command.CommandCreated.Add(command.ElapsedTime); // TODO: deal with the re-transmission // command.RetransmissionOf; // command.RetransmissionReason; // TODO: determine what to do with Resource in this context var resource = Resource.Empty; var attributesMap = new Dictionary <string, object>() { // TODO: pre-allocate constant attribute and reuse { "db.type", "redis" }, // Example: "redis.flags": None, DemandMaster { "redis.flags", command.Flags.ToString() }, }; if (command.Command != null) { // Example: "db.statement": SET; attributesMap.Add("db.statement", command.Command); } if (command.EndPoint != null) { // Example: "db.instance": Unspecified/localhost:6379[0] attributesMap.Add("db.instance", command.EndPoint.ToString() + "[" + command.Db + "]"); } var attributes = Attributes.Create(attributesMap, 0); ILinks links = null; int? childSpanCount = 0; // TODO: this is strange that IProfiledCommand doesn't give the result var status = Status.Ok; var kind = SpanKind.Client; return(SpanData.Create(context, parentSpanId, resource, name, startTimestamp, attributes, events, links, childSpanCount, status, kind, endTimestamp)); }