public Batch(Process process) { Guard.Null(process, nameof(process)); this.Process = process; this.spanMessages = PooledList <BufferWriterMemory> .Create(); }
private static bool ProcessActivityLink(ref PooledListState <JaegerSpanRef> state, ActivityLink link) { if (!state.Created) { state.List = PooledList <JaegerSpanRef> .Create(); state.Created = true; } PooledList <JaegerSpanRef> .Add(ref state.List, link.ToJaegerSpanRef()); return(true); }
private static bool ProcessActivityEvent(ref PooledListState <JaegerLog> state, ActivityEvent e) { if (!state.Created) { state.List = PooledList <JaegerLog> .Create(); state.Created = true; } PooledList <JaegerLog> .Add(ref state.List, e.ToJaegerLog()); return(true); }
private static bool ProcessActivityTag(ref TagState state, KeyValuePair <string, string> activityTag) { var jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.STRING, activityTag.Value); if (jaegerTag.VStr != null && PeerServiceKeyResolutionDictionary.TryGetValue(activityTag.Key, out int priority) && (state.PeerService == null || priority < state.PeerServicePriority)) { state.PeerService = jaegerTag.VStr; state.PeerServicePriority = priority; } PooledList <JaegerTag> .Add(ref state.Tags, jaegerTag); return(true); }
private static bool ProcessAttribute(ref TagState state, KeyValuePair <string, object> label) { var tag = label.ToJaegerTag(); if (tag.VStr != null && PeerServiceKeyResolutionDictionary.TryGetValue(label.Key, out int priority) && (state.PeerService == null || priority < state.PeerServicePriority)) { state.PeerService = tag.VStr; state.PeerServicePriority = priority; } PooledList <JaegerTag> .Add(ref state.Tags, tag); return(true); }
public static JaegerLog ToJaegerLog(this Event timedEvent) { var tags = PooledList <JaegerTag> .Create(); foreach (var attribute in timedEvent.Attributes) { PooledList <JaegerTag> .Add(ref tags, attribute.ToJaegerTag()); } // Matches what OpenTracing and OpenTelemetry defines as the event name. // https://github.com/opentracing/specification/blob/master/semantic_conventions.md#log-fields-table // https://github.com/open-telemetry/opentelemetry-specification/pull/397/files PooledList <JaegerTag> .Add(ref tags, new JaegerTag("message", JaegerTagType.STRING, vStr : timedEvent.Name)); return(new JaegerLog(timedEvent.Timestamp.ToEpochMicroseconds(), tags)); }
public static JaegerLog ToJaegerLog(this ActivityEvent timedEvent) { var jaegerTags = new EventTagsEnumerationState { Tags = PooledList <JaegerTag> .Create(), }; timedEvent.EnumerateTags(ref jaegerTags); // Matches what OpenTracing and OpenTelemetry defines as the event name. // https://github.com/opentracing/specification/blob/master/semantic_conventions.md#log-fields-table // https://github.com/open-telemetry/opentelemetry-specification/pull/397/files PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("message", JaegerTagType.STRING, vStr : timedEvent.Name)); // TODO: Use the same function as JaegerConversionExtensions or check that the perf here is acceptable. return(new JaegerLog(timedEvent.Timestamp.ToEpochMicroseconds(), jaegerTags.Tags)); }
private static bool ProcessLibraryAttribute(ref TagState state, KeyValuePair <string, object> label) { switch (label.Key) { case Resource.LibraryNameKey: PooledList <JaegerTag> .Add(ref state.Tags, label.ToJaegerTag()); break; case Resource.LibraryVersionKey: PooledList <JaegerTag> .Add(ref state.Tags, label.ToJaegerTag()); break; } return(true); }
public static JaegerLog ToJaegerLog(this ActivityEvent timedEvent) { var jaegerTags = new EventTagsEnumerationState { Tags = PooledList <JaegerTag> .Create(), }; timedEvent.EnumerateTags(ref jaegerTags); if (!jaegerTags.HasEvent) { // https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk_exporters/jaeger.md#events PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("event", JaegerTagType.STRING, vStr : timedEvent.Name)); } // TODO: Use the same function as JaegerConversionExtensions or check that the perf here is acceptable. return(new JaegerLog(timedEvent.Timestamp.ToEpochMicroseconds(), jaegerTags.Tags)); }
public static PooledList <JaegerSpanRef> ToJaegerSpanRefs(this IEnumerable <Link> links) { bool created = false; PooledList <JaegerSpanRef> references = default; foreach (var link in links ?? Array.Empty <Link>()) { if (!created) { references = PooledList <JaegerSpanRef> .Create(); created = true; } PooledList <JaegerSpanRef> .Add(ref references, link.ToJaegerSpanRef()); } return(references); }
public static JaegerLog ToJaegerLog(this Event timedEvent) { var tags = new PooledListState <JaegerTag> { Created = true, List = PooledList <JaegerTag> .Create(), }; DictionaryEnumerator <string, object, PooledListState <JaegerTag> > .AllocationFreeForEach( timedEvent.Attributes, ref tags, ProcessTagRef); // Matches what OpenTracing and OpenTelemetry defines as the event name. // https://github.com/opentracing/specification/blob/master/semantic_conventions.md#log-fields-table // https://github.com/open-telemetry/opentelemetry-specification/pull/397/files PooledList <JaegerTag> .Add(ref tags.List, new JaegerTag("message", JaegerTagType.STRING, vStr : timedEvent.Name)); return(new JaegerLog(timedEvent.Timestamp.ToEpochMicroseconds(), tags.List)); }
public static PooledList <JaegerLog> ToJaegerLogs(this IEnumerable <Event> events) { bool created = false; PooledList <JaegerLog> logs = default; foreach (var e in events ?? Array.Empty <Event>()) { if (e == null) { continue; } if (!created) { logs = PooledList <JaegerLog> .Create(); created = true; } PooledList <JaegerLog> .Add(ref logs, e.ToJaegerLog()); } return(logs); }
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())); }
internal void Clear() { PooledList <BufferWriterMemory> .Clear(ref this.spanMessages); }
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 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 static bool ProcessTag(ref PooledListState <JaegerTag> state, KeyValuePair <string, object> attribute) { PooledList <JaegerTag> .Add(ref state.List, attribute.ToJaegerTag()); return(true); }
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())); }
internal void Add(BufferWriterMemory spanMessage) { PooledList <BufferWriterMemory> .Add(ref this.spanMessages, spanMessage); }
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 Batch(Process process) { this.Process = process ?? throw new ArgumentNullException(nameof(process)); this.spanMessages = PooledList <BufferWriterMemory> .Create(); }
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())); }