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