private static Activity CreateSubstituteActivityFromCompatibleRootId(Activity currentActivity, ReadOnlySpan <char> traceId)
        {
#pragma warning disable CA2000 // Dispose objects before losing scope
            // Since we don't know when it will finish, we will not dispose
            var activity = new Activity(currentActivity.OperationName);
#pragma warning restore CA2000 // Dispose objects before losing scope
            activity.SetParentId(ActivityTraceId.CreateFromString(traceId), default, ActivityTraceFlags.None);
        public void TraceContextFormatCanParseExampleFromSpec()
        {
            var headers = new Dictionary <string, string>()
            {
                { "traceparent", "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01" },
                {
                    "tracestate",
                    "congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01"
                },
            };

            var f   = new TraceContextFormat();
            var ctx = f.Extract(headers, getter);

            Assert.Equal(ActivityTraceId.CreateFromString("0af7651916cd43dd8448eb211c80319c".AsSpan()), ctx.TraceId);
            Assert.Equal(ActivitySpanId.CreateFromString("b9c7c989f97918e1".AsSpan()), ctx.SpanId);
            Assert.True(ctx.IsRemote);
            Assert.True(ctx.IsValid);
            Assert.True((ctx.TraceOptions & ActivityTraceFlags.Recorded) != 0);

            Assert.Equal(2, ctx.Tracestate.Count());

            var first = ctx.Tracestate.First();

            Assert.Equal("congo", first.Key);
            Assert.Equal("lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4", first.Value);

            var last = ctx.Tracestate.Last();

            Assert.Equal("rojo", last.Key);
            Assert.Equal("00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01", last.Value);
        }
        internal SpanData CreateTestSpan(
            bool setAttributes = true,
            bool addEvents     = true,
            bool addLinks      = true,
            Resource resource  = null)
        {
            var startTimestamp = DateTime.UtcNow;
            var endTimestamp   = startTimestamp.AddSeconds(60);
            var eventTimestamp = DateTime.UtcNow;
            var traceId        = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());

            var spanId       = ActivitySpanId.CreateRandom();
            var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });
            var attributes   = new Dictionary <string, object>
            {
                { "stringKey", "value" },
                { "longKey", 1L },
                { "longKey2", 1 },
                { "doubleKey", 1D },
                { "doubleKey2", 1F },
                { "boolKey", true },
            };
            var events = new List <Event>
            {
                new Event(
                    "Event1",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
                new Event(
                    "Event2",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
            };

            var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());

            return(new SpanData(
                       "Name",
                       new SpanContext(traceId, spanId, ActivityTraceFlags.Recorded),
                       parentSpanId,
                       SpanKind.Client,
                       startTimestamp,
                       setAttributes ? attributes : null,
                       addEvents ? events : null,
                       addLinks ? new[] { new Link(new SpanContext(
                                                       traceId,
                                                       linkedSpanId,
                                                       ActivityTraceFlags.Recorded)), } : null,
                       resource,
                       Status.Ok,
                       endTimestamp));
        }
Esempio n. 4
0
        public void TraceContextFormatCanParseExampleFromSpec()
        {
            var headers = new Dictionary <string, string>
            {
                { TraceParent, $"00-{TraceId}-{SpanId}-01" },
                { TraceState, $"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01" },
            };

            var f   = new TraceContextFormat();
            var ctx = f.Extract(headers, Getter);

            Assert.Equal(ActivityTraceId.CreateFromString(TraceId.AsSpan()), ctx.TraceId);
            Assert.Equal(ActivitySpanId.CreateFromString(SpanId.AsSpan()), ctx.SpanId);
            Assert.True(ctx.IsRemote);
            Assert.True(ctx.IsValid);
            Assert.True((ctx.TraceOptions & ActivityTraceFlags.Recorded) != 0);

            Assert.Equal(2, ctx.Tracestate.Count());

            var first = ctx.Tracestate.First();

            Assert.Equal("congo", first.Key);
            Assert.Equal("lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4", first.Value);

            var last = ctx.Tracestate.Last();

            Assert.Equal("rojo", last.Key);
            Assert.Equal($"00-{TraceId}-00f067aa0ba902b7-01", last.Value);
        }
 public ActivityContext(string traceParent, string traceState)
 {
     SpanId     = ActivitySpanId.CreateFromString(traceParent.AsSpan(36, 16));
     TraceId    = ActivityTraceId.CreateFromString(traceParent.AsSpan(3, 32));
     Flags      = (ActivityTraceFlags)HexByteFromChars(traceParent[53], traceParent[54]);
     TraceState = new ActivityTraceState(traceState);
 }
Esempio n. 6
0
        public override void OnEvent(KeyValuePair <string, object> evnt, DiagnosticListener ignored)
        {
            Activity currentActivity = Activity.Current;

            switch (evnt.Key)
            {
            case "Microsoft.Azure.ServiceBus.ProcessSession.Start":
            case "Microsoft.Azure.ServiceBus.Process.Start":
                // if Activity is W3C, but there is a parent id which is not W3C.
                if (currentActivity.IdFormat == ActivityIdFormat.W3C && !string.IsNullOrEmpty(currentActivity.ParentId) && currentActivity.ParentSpanId == default)
                {
                    // if hierarchical parent has compatible rootId, reuse it and keep legacy parentId
                    if (W3CUtilities.TryGetTraceId(currentActivity.ParentId, out var traceId))
                    {
#pragma warning disable CA2000 // Dispose objects before losing scope
                        // Since we don't know when it will finish, we will not dispose
                        var backCompatActivity = new Activity(currentActivity.OperationName);
#pragma warning restore CA2000 // Dispose objects before losing scope
                        backCompatActivity.SetParentId(ActivityTraceId.CreateFromString(traceId), default, currentActivity.ActivityTraceFlags);
                        backCompatActivity.Start();
                        backCompatActivity.AddTag("__legacyParentId", currentActivity.ParentId);
                        foreach (var tag in currentActivity.Tags)
                        {
                            backCompatActivity.AddTag(tag.Key, tag.Value);
                        }

                        foreach (var baggage in currentActivity.Baggage)
                        {
                            backCompatActivity.AddBaggage(baggage.Key, baggage.Value);
                        }
                    }
Esempio n. 7
0
        private static PropagationContext ExtractFromSingleHeader <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            try
            {
                var header = getter(carrier, XB3Combined)?.FirstOrDefault();
                if (string.IsNullOrWhiteSpace(header))
                {
                    return(context);
                }

                var parts = header.Split(XB3CombinedDelimiter);
                if (parts.Length < 2 || parts.Length > 4)
                {
                    return(context);
                }

                var traceIdStr = parts[0];
                if (string.IsNullOrWhiteSpace(traceIdStr))
                {
                    return(context);
                }

                if (traceIdStr.Length == 16)
                {
                    // This is an 8-byte traceID.
                    traceIdStr = UpperTraceId + traceIdStr;
                }

                var traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan());

                var spanIdStr = parts[1];
                if (string.IsNullOrWhiteSpace(spanIdStr))
                {
                    return(context);
                }

                var spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan());

                var traceOptions = ActivityTraceFlags.None;
                if (parts.Length > 2)
                {
                    var traceFlagsStr = parts[2];
                    if (SampledValues.Contains(traceFlagsStr) ||
                        FlagsValue.Equals(traceFlagsStr, StringComparison.Ordinal))
                    {
                        traceOptions |= ActivityTraceFlags.Recorded;
                    }
                }

                return(new PropagationContext(
                           new ActivityContext(traceId, spanId, traceOptions, isRemote: true),
                           context.Baggage));
            }
            catch (Exception e)
            {
                OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(B3Propagator), e);
                return(context);
            }
        }
Esempio n. 8
0
        /// <inheritdoc/>
        public SpanContext Extract <T>(T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            if (carrier == null)
            {
                OpenTelemetrySdkEventSource.Log.FailedToExtractContext("null carrier");
                return(SpanContext.BlankRemote);
            }

            if (getter == null)
            {
                OpenTelemetrySdkEventSource.Log.FailedToExtractContext("null getter");
                return(SpanContext.BlankRemote);
            }

            try
            {
                ActivityTraceId traceId;
                var             traceIdStr = getter(carrier, XB3TraceId)?.FirstOrDefault();
                if (traceIdStr != null)
                {
                    if (traceIdStr.Length == 16)
                    {
                        // This is an 8-byte traceID.
                        traceIdStr = UpperTraceId + traceIdStr;
                    }

                    traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan());
                }
                else
                {
                    return(SpanContext.BlankRemote);
                }

                ActivitySpanId spanId;
                var            spanIdStr = getter(carrier, XB3SpanId)?.FirstOrDefault();
                if (spanIdStr != null)
                {
                    spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan());
                }
                else
                {
                    return(SpanContext.BlankRemote);
                }

                var traceOptions = ActivityTraceFlags.None;
                if (SampledValue.Equals(getter(carrier, XB3Sampled)?.FirstOrDefault()) ||
                    FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault()))
                {
                    traceOptions |= ActivityTraceFlags.Recorded;
                }

                return(new SpanContext(traceId, spanId, traceOptions));
            }
            catch (Exception e)
            {
                OpenTelemetrySdkEventSource.Log.ContextExtractException(e);
                return(SpanContext.BlankRemote);
            }
        }
Esempio n. 9
0
        private Activity CreateTestActivity()
        {
            var startTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);
            var endTimestamp   = startTimestamp.AddSeconds(60);
            var eventTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);

            var traceId      = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());
            var spanId       = ActivitySpanId.CreateFromString("6a69db47429ea340".AsSpan());
            var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });
            var attributes   = new Dictionary <string, object>
            {
                { "stringKey", "value" },
                { "longKey", 1L },
                { "longKey2", 1 },
                { "doubleKey", 1D },
                { "doubleKey2", 1F },
                { "boolKey", true },
            };
            var events = new List <ActivityEvent>
            {
                new ActivityEvent(
                    "Event1",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
                new ActivityEvent(
                    "Event2",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
            };

            var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());

            var activitySource = new ActivitySource(nameof(CreateTestActivity));

            var tags = attributes.Select(kvp => new KeyValuePair <string, string>(kvp.Key, kvp.Value.ToString()));

            var links = new[] {
                new ActivityLink(new ActivityContext(
                                     traceId,
                                     linkedSpanId,
                                     ActivityTraceFlags.Recorded)),
            };

            return(activitySource.StartActivity(
                       "Name",
                       ActivityKind.Client,
                       parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded),
                       tags,
                       links,
                       startTime: startTimestamp));
        }
Esempio n. 10
0
        public override ActivityContext Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var reader = context.Reader;

            switch (reader.CurrentBsonType)
            {
            case BsonType.Null:
                reader.ReadNull();
                return(default);

            case BsonType.Document:
                reader.ReadStartDocument();

                var isRemote   = false;
                var traceId    = default(ActivityTraceId);
                var traceFlags = default(ActivityTraceFlags);
                var traceState = (string?)null;
                var spanId     = default(ActivitySpanId);

                while (reader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var name = reader.ReadName(Utf8NameDecoder.Instance);

                    switch (name)
                    {
                    case nameof(ActivityContext.IsRemote):
                        isRemote = reader.ReadBoolean();
                        break;

                    case nameof(ActivityContext.TraceId):
                        traceId = ActivityTraceId.CreateFromString(reader.ReadString());
                        break;

                    case nameof(ActivityContext.TraceFlags):
                        traceFlags = Enum.Parse <ActivityTraceFlags>(reader.ReadString() !);
                        break;

                    case nameof(ActivityContext.TraceState):
                        traceState = reader.ReadString();
                        break;

                    case nameof(ActivityContext.SpanId):
                        spanId = ActivitySpanId.CreateFromString(reader.ReadString());
                        break;

                    default:
                        throw new BsonSerializationException($"Invalid property {name}.");
                    }
                }

                reader.ReadEndDocument();

                return(new ActivityContext(traceId, spanId, traceFlags, traceState, isRemote));

            default:
                throw new BsonSerializationException($"Expected BsonType.Document or JsonTokenType.Null, got {reader.CurrentBsonType}.");
            }
        }
        private SpanData CreateTestSpan()
        {
            var startTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);
            var endTimestamp   = startTimestamp.AddSeconds(60);
            var eventTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);

            var traceId      = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());
            var spanId       = ActivitySpanId.CreateFromString("6a69db47429ea340".AsSpan());
            var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });
            var attributes   = new Dictionary <string, object>
            {
                { "stringKey", "value" },
                { "longKey", 1L },
                { "longKey2", 1 },
                { "doubleKey", 1D },
                { "doubleKey2", 1F },
                { "boolKey", true },
            };
            var events = new List <Event>
            {
                new Event(
                    "Event1",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
                new Event(
                    "Event2",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
            };

            var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());

            var link = new Link(new SpanContext(
                                    traceId,
                                    linkedSpanId,
                                    ActivityTraceFlags.Recorded));

            return(new SpanData(
                       "Name",
                       new SpanContext(traceId, spanId, ActivityTraceFlags.Recorded),
                       parentSpanId,
                       SpanKind.Client,
                       startTimestamp,
                       attributes,
                       events,
                       new[] { link, },
                       null,
                       Status.Ok,
                       endTimestamp));
        }
Esempio n. 12
0
        private Span CreateTestSpan()
        {
            var startTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);
            var endTimestamp   = startTimestamp.AddSeconds(60);
            var eventTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);

            var traceId      = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());
            var spanId       = "6a69db47429ea340";
            var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });
            var attributes   = new Dictionary <string, object>
            {
                { "stringKey", "value" },
                { "longKey", 1L },
                { "longKey2", 1 },
                { "doubleKey", 1D },
                { "doubleKey2", 1F },
                { "boolKey", true },
            };
            var events = new List <Event>
            {
                new Event(
                    "Event1",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
                new Event(
                    "Event2",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
            };

            var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());

            var link = new Link(new SpanContext(
                                    traceId,
                                    linkedSpanId,
                                    ActivityTraceFlags.Recorded));

            var span = (Span)tracer
                       .StartSpan("Name", new SpanContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), SpanKind.Client,
                                  new SpanCreationOptions
            {
                StartTimestamp = startTimestamp,
                Links          = new[] { link },
            });

            var spanContextSetter = typeof(Span).GetMethod("set_Context", BindingFlags.Instance | BindingFlags.NonPublic);

            ActivitySpanId activitySpanId = ActivitySpanId.CreateFromString(spanId.AsSpan());

            spanContextSetter.Invoke(span, new [] { (object)new SpanContext(in traceId, in activitySpanId, ActivityTraceFlags.Recorded) });
Esempio n. 13
0
        /// <inheritdoc/>
        public SpanContext Extract <T>(T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            if (carrier == null)
            {
                throw new ArgumentNullException(nameof(carrier));
            }

            if (getter == null)
            {
                throw new ArgumentNullException(nameof(getter));
            }

            try
            {
                ActivityTraceId traceId;
                var             traceIdStr = getter(carrier, XB3TraceId)?.FirstOrDefault();
                if (traceIdStr != null)
                {
                    if (traceIdStr.Length == 16)
                    {
                        // This is an 8-byte traceID.
                        traceIdStr = UpperTraceId + traceIdStr;
                    }

                    traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan());
                }
                else
                {
                    throw new SpanContextParseException("Missing X_B3_TRACE_ID.");
                }

                ActivitySpanId spanId;
                var            spanIdStr = getter(carrier, XB3SpanId)?.FirstOrDefault();
                if (spanIdStr != null)
                {
                    spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan());
                }
                else
                {
                    throw new SpanContextParseException("Missing X_B3_SPAN_ID.");
                }

                var traceOptions = ActivityTraceFlags.None;
                if (SampledValue.Equals(getter(carrier, XB3Sampled)?.FirstOrDefault()) ||
                    FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault()))
                {
                    traceOptions |= ActivityTraceFlags.Recorded;
                }

                return(new SpanContext(traceId, spanId, traceOptions));
            }
            catch (Exception e)
            {
                throw new SpanContextParseException("Invalid input.", e);
            }
        }
        public void TestExtractTraceHeader()
        {
            var carrier = new Dictionary <string, string>()
            {
                { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1" },
            };
            var traceId         = ActivityTraceId.CreateFromString(TraceId.AsSpan());
            var parentId        = ActivitySpanId.CreateFromString(ParentId.AsSpan());
            var traceFlags      = ActivityTraceFlags.Recorded;
            var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true);

            Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter));
Esempio n. 15
0
        public override ActivityContext Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            switch (reader.TokenType)
            {
            case JsonTokenType.Null:
                return(default);

            case JsonTokenType.StartObject:
                var isRemote   = false;
                var traceId    = default(ActivityTraceId);
                var traceFlags = default(ActivityTraceFlags);
                var traceState = (string?)null;
                var spanId     = default(ActivitySpanId);

                while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
                {
                    var property = reader.GetString();

                    reader.Read();

                    switch (property)
                    {
                    case "isRemote":
                        isRemote = reader.GetBoolean();
                        break;

                    case "traceId":
                        traceId = ActivityTraceId.CreateFromString(reader.GetString());
                        break;

                    case "traceFlags":
                        traceFlags = Enum.Parse <ActivityTraceFlags>(reader.GetString() !);
                        break;

                    case "traceState":
                        traceState = reader.GetString();
                        break;

                    case "spanId":
                        spanId = ActivitySpanId.CreateFromString(reader.GetString());
                        break;

                    default:
                        throw new JsonException($"Invalid property {property}.");
                    }
                }

                return(new ActivityContext(traceId, spanId, traceFlags, traceState, isRemote));

            default:
                throw new JsonException($"Expected JsonTokenType.StartObject or JsonTokenType.Null, got {reader.TokenType}.");
            }
        }
        public void TestInjectTraceHeaderNotSampled()
        {
            var carrier         = new Dictionary <string, string>();
            var traceId         = ActivityTraceId.CreateFromString(TraceId.AsSpan());
            var parentId        = ActivitySpanId.CreateFromString(ParentId.AsSpan());
            var traceFlags      = ActivityTraceFlags.None;
            var activityContext = new ActivityContext(traceId, parentId, traceFlags);

            this.awsXRayPropagator.Inject(new PropagationContext(activityContext, default), carrier, Setter);

            Assert.True(carrier.ContainsKey(AWSXRayTraceHeaderKey));
            Assert.Equal("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0", carrier[AWSXRayTraceHeaderKey]);
        }
        private static ActivityContext GetActivityContext(Context context)
        {
            if (context == null || string.IsNullOrEmpty(context.TraceId) || string.IsNullOrEmpty(context.SpanId))
            {
                return(default(ActivityContext));
            }

            Enum.TryParse(context.TraceFlags, out ActivityTraceFlags flags);
            return(new ActivityContext(
                       ActivityTraceId.CreateFromString(context.TraceId.ToCharArray()),
                       ActivitySpanId.CreateFromString(context.SpanId.ToCharArray()),
                       flags,
                       context.TraceState));
        }
Esempio n. 18
0
        public void TraceContextFormatNotSampled()
        {
            var headers = new Dictionary <string, string>()
            {
                { "traceparent", "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-00" },
            };

            var f   = new TraceContextFormat();
            var ctx = f.Extract(headers, getter);

            Assert.Equal(ActivityTraceId.CreateFromString("0af7651916cd43dd8448eb211c80319c".AsSpan()), ctx.TraceId);
            Assert.Equal(ActivitySpanId.CreateFromString("b9c7c989f97918e1".AsSpan()), ctx.SpanId);
            Assert.True((ctx.TraceOptions & ActivityTraceFlags.Recorded) == 0);
        }
Esempio n. 19
0
        private static PropagationContext ExtractFromMultipleHeaders <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            try
            {
                ActivityTraceId traceId;
                var             traceIdStr = getter(carrier, XB3TraceId)?.FirstOrDefault();
                if (traceIdStr != null)
                {
                    if (traceIdStr.Length == 16)
                    {
                        // This is an 8-byte traceID.
                        traceIdStr = UpperTraceId + traceIdStr;
                    }

                    traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan());
                }
                else
                {
                    return(context);
                }

                ActivitySpanId spanId;
                var            spanIdStr = getter(carrier, XB3SpanId)?.FirstOrDefault();
                if (spanIdStr != null)
                {
                    spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan());
                }
                else
                {
                    return(context);
                }

                var traceOptions = ActivityTraceFlags.None;
                if (SampledValues.Contains(getter(carrier, XB3Sampled)?.FirstOrDefault()) ||
                    FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault(), StringComparison.Ordinal))
                {
                    traceOptions |= ActivityTraceFlags.Recorded;
                }

                return(new PropagationContext(
                           new ActivityContext(traceId, spanId, traceOptions, isRemote: true),
                           context.Baggage));
            }
            catch (Exception e)
            {
                OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(B3Propagator), e);
                return(context);
            }
        }
Esempio n. 20
0
        public void TraceIdBeforeStartTests()
        {
            try
            {
                Activity activity;

                // from traceparent header
                activity = new Activity("activity1");
                activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01");
                Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString());

                // from explicit TraceId and SpanId
                activity = new Activity("activity2");
                activity.SetParentId(
                    ActivityTraceId.CreateFromString("0123456789abcdef0123456789abcdef".AsSpan()),
                    ActivitySpanId.CreateFromString("0123456789abcdef".AsSpan()));

                Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString());

                // from in-proc parent
                Activity parent = new Activity("parent");
                parent.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01");
                parent.Start();

                activity = new Activity("child");
                activity.Start();
                Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString());
                parent.Stop();
                activity.Stop();

                // no parent
                Activity.DefaultIdFormat      = ActivityIdFormat.W3C;
                Activity.ForceDefaultIdFormat = true;

                activity = new Activity("activity3");
                Assert.Equal("00000000000000000000000000000000", activity.TraceId.ToHexString());

                // from invalid traceparent header
                activity.SetParentId("123");
                Assert.Equal("00000000000000000000000000000000", activity.TraceId.ToHexString());
            }
            finally
            {
                Activity.ForceDefaultIdFormat = false;
                Activity.DefaultIdFormat      = ActivityIdFormat.Hierarchical;
                Activity.Current = null;
            }
        }
Esempio n. 21
0
        public void TraceContextFormatNotSampled()
        {
            var headers = new Dictionary <string, string>
            {
                { TraceParent, $"00-{TraceId}-{SpanId}-00" },
            };

            var f   = new TraceContextFormat();
            var ctx = f.Extract(headers, Getter);

            Assert.Equal(ActivityTraceId.CreateFromString(TraceId.AsSpan()), ctx.TraceId);
            Assert.Equal(ActivitySpanId.CreateFromString(SpanId.AsSpan()), ctx.SpanId);
            Assert.True((ctx.TraceOptions & ActivityTraceFlags.Recorded) == 0);
            Assert.True(ctx.IsRemote);
            Assert.True(ctx.IsValid);
        }
Esempio n. 22
0
        public void TestGenerateTraceIdForNonRootNodeNotSampled()
        {
            var activity = new Activity("Test");
            var traceId  = ActivityTraceId.CreateFromString("12345678901234567890123456789012".AsSpan());
            var parentId = ActivitySpanId.CreateFromString("1234567890123456".AsSpan());

            activity.SetParentId(traceId, parentId, ActivityTraceFlags.None);

            using (Sdk.CreateTracerProviderBuilder().AddXRayTraceId().Build())
            {
                activity.Start();

                Assert.Equal("12345678901234567890123456789012", activity.TraceId.ToHexString());
                Assert.Equal("1234567890123456", activity.ParentSpanId.ToHexString());
                Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags);
            }
        }
        public void BasicActivityTracking()
        {
            var healthReporter = new Mock <IHealthReporter>();
            var observer       = new TestObserver();
            var ActivityName   = GetRandomName();

            var sources = new List <ActivitySourceConfiguration>(new[]
            {
                new ActivitySourceConfiguration
                {
                    ActivitySourceName = SourceOneName,
                    ActivityName       = ActivityName,
                    CapturedData       = ActivitySamplingResult.AllData,
                    CapturedEvents     = CapturedActivityEvents.Both
                }
            });

            using (var input = new ActivitySourceInput(new ActivitySourceInputConfiguration {
                Sources = sources
            }, healthReporter.Object))
            {
                input.Subscribe(observer);

                var ctx = new ActivityContext(
                    ActivityTraceId.CreateFromString(WellKnownTraceId),
                    ActivitySpanId.CreateFromString(SpanIdOne),
                    ActivityTraceFlags.None);
                var activity = SourceOne.StartActivity(ActivityName, ActivityKind.Internal, ctx);
                activity.Stop();
            }

            healthReporter.VerifyNoOtherCalls();

            Assert.Equal(2, observer.Data.Count);
            Assert.True(observer.Completed);
            Assert.Null(observer.Error);

            Assert.True(observer.Data.TryDequeue(out EventData e));
            VerifyActivityEvent(e, ActivityName, SourceOneName, CapturedActivityEvents.Start, WellKnownTraceId, SpanIdOne);
            Assert.True(observer.Data.TryDequeue(out e));
            VerifyActivityEvent(e, ActivityName, SourceOneName, CapturedActivityEvents.Stop, WellKnownTraceId, SpanIdOne);
        }
Esempio n. 24
0
        public static TraceParent CreateFromString(string traceparent)
        {
            if (string.IsNullOrWhiteSpace(traceparent))
            {
                throw new ArgumentException("Invalid traceparent", nameof(traceparent));
            }

            var vals = traceparent.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);

            if (vals.Length != 4)
            {
                throw new ArgumentException("Invalid traceparent format: {traceparent}", traceparent);
            }

            var traceId = ActivityTraceId.CreateFromString(vals[1].AsSpan());
            var spanId  = ActivitySpanId.CreateFromString(vals[2].AsSpan());
            var flags   = vals[3] == "01" ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None;

            // TODO: validate each item
            return(new TraceParent(traceId, spanId, flags, vals[0]));
        }
        private static Activity CopyFromCompatibleRoot(Activity from)
        {
            var copy = new Activity(from.OperationName);

            copy.SetParentId(ActivityTraceId.CreateFromString(from.RootId.AsSpan()),
                             default(ActivitySpanId), from.ActivityTraceFlags);

            foreach (var tag in from.Tags)
            {
                copy.AddTag(tag.Key, tag.Value);
            }

            foreach (var baggage in from.Baggage)
            {
                copy.AddBaggage(baggage.Key, baggage.Value);
            }

            copy.TraceStateString = from.TraceStateString;

            return(copy);
        }
        public void TraceContextFormatCanParseExampleFromSpec()
        {
            var headers = new Dictionary <string, string>
            {
                { TraceParent, $"00-{TraceId}-{SpanId}-01" },
                { TraceState, $"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01" },
            };

            var f   = new TraceContextFormatActivity();
            var ctx = f.Extract(headers, Getter);

            Assert.Equal(ActivityTraceId.CreateFromString(TraceId.AsSpan()), ctx.TraceId);
            Assert.Equal(ActivitySpanId.CreateFromString(SpanId.AsSpan()), ctx.SpanId);

            // TODO: when ActivityContext supports IsRemote
            // Assert.True(ctx.IsRemote);

            Assert.True(ctx.IsValid());
            Assert.True((ctx.TraceFlags & ActivityTraceFlags.Recorded) != 0);

            Assert.Equal($"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01", ctx.TraceState);
        }
Esempio n. 27
0
        private async Task <TelemetrySpan> PreBefore(CapHeader header)
        {
            if (!header.ContainsKey(CurrentDeviceId))
            {
                throw new Exception("currentDeviceId不可为空");
            }

            _dbContextFactory.IsTransaction = true;

            var deviceId  = Convert.ToInt32(header[CurrentDeviceId]);
            var deviceDto = await _deviceService.GetDeviceById_Pref(deviceId);

            _current.Device = deviceDto;

            var tracer      = _tracerFactory.GetTracer(header[CapMsgName]);
            var traceId     = header.ContainsKey(TraceId) ? header[TraceId] : CommonHelper.NewSequentialGuid().ToString();
            var spanId      = tracer.CurrentSpan.Context.SpanId;
            var spanContext = new SpanContext(
                ActivityTraceId.CreateFromString(traceId),
                spanId, //  ActivitySpanId.CreateFromString(""),
                ActivityTraceFlags.None);

            return(tracer.StartSpan(header[CapMsgName], spanContext, SpanKind.Server));
        }
Esempio n. 28
0
        internal static Activity CreateTestActivity(
            bool setAttributes = true,
            Dictionary <string, object> additionalAttributes = null,
            bool addEvents    = true,
            bool addLinks     = true,
            Resource resource = null,
            ActivityKind kind = ActivityKind.Client)
        {
            var startTimestamp = DateTime.UtcNow;
            var endTimestamp   = startTimestamp.AddSeconds(60);
            var eventTimestamp = DateTime.UtcNow;
            var traceId        = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());

            var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });

            var attributes = new Dictionary <string, object>
            {
                { "stringKey", "value" },
                { "longKey", 1L },
                { "longKey2", 1 },
                { "doubleKey", 1D },
                { "doubleKey2", 1F },
                { "boolKey", true },
                { "int_array", new int[] { 1, 2 } },
                { "bool_array", new bool[] { true, false } },
                { "double_array", new double[] { 1.0, 1.1 } },
                { "string_array", new string[] { "a", "b" } },
            };

            if (additionalAttributes != null)
            {
                foreach (var attribute in additionalAttributes)
                {
                    attributes.Add(attribute.Key, attribute.Value);
                }
            }

            var events = new List <ActivityEvent>
            {
                new ActivityEvent(
                    "Event1",
                    eventTimestamp,
                    new ActivityTagsCollection(new Dictionary <string, object>
                {
                    { "key", "value" },
                })),
                new ActivityEvent(
                    "Event2",
                    eventTimestamp,
                    new ActivityTagsCollection(new Dictionary <string, object>
                {
                    { "key", "value" },
                })),
            };

            var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());

            var activitySource = new ActivitySource(nameof(CreateTestActivity));

            var tags = setAttributes ?
                       attributes
                    : null;
            var links = addLinks ?
                        new[]
            {
                new ActivityLink(new ActivityContext(
                                     traceId,
                                     linkedSpanId,
                                     ActivityTraceFlags.Recorded)),
            }
                    : null;

            var activity = activitySource.StartActivity(
                "Name",
                kind,
                parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded),
                tags,
                links,
                startTime: startTimestamp);

            if (addEvents)
            {
                foreach (var evnt in events)
                {
                    activity.AddEvent(evnt);
                }
            }

            activity.SetEndTime(endTimestamp);
            activity.Stop();

            return(activity);
        }
Esempio n. 29
0
        internal static bool TryExtractTraceparent(string traceparent, out ActivityTraceId traceId, out ActivitySpanId spanId, out ActivityTraceFlags traceOptions)
        {
            // from https://github.com/w3c/distributed-tracing/blob/master/trace_context/HTTP_HEADER_FORMAT.md
            // traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01

            traceId      = default;
            spanId       = default;
            traceOptions = default;
            var bestAttempt = false;

            if (string.IsNullOrWhiteSpace(traceparent) || traceparent.Length < TraceparentLengthV0)
            {
                return(false);
            }

            // if version does not end with delimiter
            if (traceparent[VersionPrefixIdLength - 1] != '-')
            {
                return(false);
            }

            // or version is not a hex (will throw)
            var version0 = HexCharToByte(traceparent[0]);
            var version1 = HexCharToByte(traceparent[1]);

            if (version0 == 0xf && version1 == 0xf)
            {
                return(false);
            }

            if (version0 > 0)
            {
                // expected version is 00
                // for higher versions - best attempt parsing of trace id, span id, etc.
                bestAttempt = true;
            }

            if (traceparent[VersionAndTraceIdLength - 1] != '-')
            {
                return(false);
            }

            try
            {
                traceId = ActivityTraceId.CreateFromString(traceparent.AsSpan().Slice(VersionPrefixIdLength, TraceIdLength));
            }
            catch (ArgumentOutOfRangeException)
            {
                // it's ok to still parse tracestate
                return(false);
            }

            if (traceparent[VersionAndTraceIdAndSpanIdLength - 1] != '-')
            {
                return(false);
            }

            byte options1;

            try
            {
                spanId   = ActivitySpanId.CreateFromString(traceparent.AsSpan().Slice(VersionAndTraceIdLength, SpanIdLength));
                options1 = HexCharToByte(traceparent[VersionAndTraceIdAndSpanIdLength + 1]);
            }
            catch (ArgumentOutOfRangeException)
            {
                // it's ok to still parse tracestate
                return(false);
            }

            if ((options1 & 1) == 1)
            {
                traceOptions |= ActivityTraceFlags.Recorded;
            }

            if ((!bestAttempt) && (traceparent.Length != VersionAndTraceIdAndSpanIdLength + OptionsLength))
            {
                return(false);
            }

            if (bestAttempt)
            {
                if ((traceparent.Length > TraceparentLengthV0) && (traceparent[TraceparentLengthV0] != '-'))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 30
0
        internal Span CreateTestSpan(bool setAttributes = true,
                                     bool addEvents     = true,
                                     bool addLinks      = true)
        {
            var startTimestamp = DateTime.UtcNow;
            var endTimestamp   = startTimestamp.AddSeconds(60);
            var eventTimestamp = DateTime.UtcNow;
            var traceId        = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());

            var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });
            var attributes   = new Dictionary <string, object>
            {
                { "stringKey", "value" },
                { "longKey", 1L },
                { "longKey2", 1 },
                { "doubleKey", 1D },
                { "doubleKey2", 1F },
                { "boolKey", true },
            };
            var events = new List <Event>
            {
                new Event(
                    "Event1",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
                new Event(
                    "Event2",
                    eventTimestamp,
                    new Dictionary <string, object>
                {
                    { "key", "value" },
                }
                    ),
            };

            var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());

            var link = new Link(new SpanContext(
                                    traceId,
                                    linkedSpanId,
                                    ActivityTraceFlags.Recorded));

            var span = (Span)tracer
                       .StartSpan("Name", new SpanContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), SpanKind.Client, startTimestamp);

            if (addLinks)
            {
                span.AddLink(link);
            }

            if (setAttributes)
            {
                foreach (var attribute in attributes)
                {
                    span.SetAttribute(attribute);
                }
            }

            if (addEvents)
            {
                foreach (var evnt in events)
                {
                    span.AddEvent(evnt);
                }
            }

            span.Status = Status.Ok;

            span.End(endTimestamp);
            return(span);
        }