Example #1
0
        public void InvalidTracestate(string tracestate, int validEntriesCount)
        {
            var tracestateEntries = new List <KeyValuePair <string, string> >();

            Assert.False(TracestateUtils.AppendTracestate(tracestate, tracestateEntries));
            Assert.Equal(validEntriesCount, tracestateEntries.Count);
        }
Example #2
0
        public void EmptyTracestate(string tracestate)
        {
            var tracestateEntries = new List <KeyValuePair <string, string> >();

            Assert.False(TracestateUtils.AppendTracestate(tracestate, tracestateEntries));
            Assert.Empty(tracestateEntries);
        }
Example #3
0
        private static ActivityAndTracestate FromParentSpanContext(string spanName, SpanContext parentContext)
        {
            var activity = new Activity(spanName);

            IEnumerable <KeyValuePair <string, string> > tracestate = null;

            if (parentContext != null && parentContext.IsValid)
            {
                activity.SetParentId(parentContext.TraceId,
                                     parentContext.SpanId,
                                     parentContext.TraceOptions);
                if (parentContext.Tracestate != null && parentContext.Tracestate.Any())
                {
                    activity.TraceStateString = TracestateUtils.GetString(parentContext.Tracestate);
                    tracestate = parentContext.Tracestate;
                }
            }

            activity.SetIdFormat(ActivityIdFormat.W3C);

            var originalActivity = Activity.Current;

            activity.Start();
            Activity.Current = originalActivity;

            return(new ActivityAndTracestate(activity, tracestate));
        }
        public void StartSpanFromExplicitActivity()
        {
            var parentActivity = new Activity(SpanName)
                                 .SetIdFormat(ActivityIdFormat.W3C)
                                 .Start();

            parentActivity.TraceStateString = "k1=v1,k2=v2";
            parentActivity.Stop();

            var childSpan = new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                            .SetSpanKind(SpanKind.Internal)
                            .SetParent(parentActivity)
                            .StartSpan();

            Assert.True(childSpan.Context.IsValid);
            Assert.Equal(parentActivity.TraceId, childSpan.Context.TraceId);
            Assert.Equal(parentActivity.SpanId, ((Span)childSpan).ParentSpanId);

            var activity = ((Span)childSpan).Activity;

            Assert.NotNull(activity);
            Assert.Null(Activity.Current);
            Assert.Equal(activity.TraceId, parentActivity.TraceId);
            Assert.Equal(activity.ParentSpanId, parentActivity.SpanId);
            Assert.Equal(activity.SpanId, childSpan.Context.SpanId);
            Assert.Equal("k1=v1,k2=v2", TracestateUtils.GetString(childSpan.Context.Tracestate));
        }
        public void ValidPair(string pair)
        {
            var builder = Tracestate.Builder;

            Assert.True(TracestateUtils.TryExtractTracestate(pair, builder));
            Assert.Equal("k=v", builder.Build().ToString());
        }
        public void ValidPairs(string tracestate)
        {
            var builder = Tracestate.Builder;

            Assert.True(TracestateUtils.TryExtractTracestate(tracestate, builder));
            Assert.Equal("k1=v1,k2=v2", builder.Build().ToString());
        }
        public void InvalidTracestate(string tracestate, int validEntriesCount)
        {
            var builder = Tracestate.Builder;

            Assert.False(TracestateUtils.TryExtractTracestate(tracestate, builder));
            Assert.Equal(validEntriesCount, builder.Build().Entries.Count());
        }
        public void EmptyTracestate(string tracestate)
        {
            var builder = Tracestate.Builder;

            Assert.True(TracestateUtils.TryExtractTracestate(tracestate, builder));
            Assert.Empty(builder.Build().Entries);
        }
Example #9
0
        public void TooManyEntries()
        {
            var tracestateEntries = new List <KeyValuePair <string, string> >();
            var tracestate        =
                "k0=v,k1=v,k2=v,k3=v,k4=v,k5=v,k6=v,k7=v1,k8=v,k9=v,k10=v,k11=v,k12=v,k13=v,k14=v,k15=v,k16=v,k17=v,k18=v,k19=v,k20=v,k21=v,k22=v,k23=v,k24=v,k25=v,k26=v,k27=v1,k28=v,k29=v,k30=v,k31=v,k32=v";

            Assert.False(TracestateUtils.AppendTracestate(tracestate, tracestateEntries));
            Assert.Empty(tracestateEntries);
        }
        public void TooManyEntries()
        {
            var builder    = Tracestate.Builder;
            var tracestate =
                "k0=v,k1=v,k2=v,k3=v,k4=v,k5=v,k6=v,k7=v1,k8=v,k9=v,k10=v,k11=v,k12=v,k13=v,k14=v,k15=v,k16=v,k17=v,k18=v,k19=v,k20=v,k21=v,k22=v,k23=v,k24=v,k25=v,k26=v,k27=v1,k28=v,k29=v,k30=v,k31=v,k32=v,k33=v";

            Assert.False(TracestateUtils.TryExtractTracestate(tracestate, builder));
            Assert.Throws <ArgumentException>(() => builder.Build());
        }
Example #11
0
        public void ValidPair(string pair, string expectedKey, string expectedValue)
        {
            var tracestateEntries = new List <KeyValuePair <string, string> >();

            Assert.True(TracestateUtils.AppendTracestate(pair, tracestateEntries));
            Assert.Single(tracestateEntries);
            Assert.Equal(new KeyValuePair <string, string>(expectedKey, expectedValue), tracestateEntries.Single());
            Assert.Equal($"{expectedKey}={expectedValue}", TracestateUtils.GetString(tracestateEntries));
        }
Example #12
0
        public void ValidPair(string pair)
        {
            var tracestateEntries = new List <KeyValuePair <string, string> >();

            Assert.True(TracestateUtils.AppendTracestate(pair, tracestateEntries));
            Assert.Single(tracestateEntries);
            Assert.Equal(new KeyValuePair <string, string>("k", "v"), tracestateEntries.Single());
            Assert.Equal("k=v", TracestateUtils.GetString(tracestateEntries));
        }
Example #13
0
        public void ValidPairs(string tracestate)
        {
            var tracestateEntries = new List <KeyValuePair <string, string> >();

            Assert.True(TracestateUtils.AppendTracestate(tracestate, tracestateEntries));
            Assert.Equal(2, tracestateEntries.Count);
            Assert.Contains(new KeyValuePair <string, string>("k1", "v1"), tracestateEntries);
            Assert.Contains(new KeyValuePair <string, string>("k2", "v2"), tracestateEntries);

            Assert.Equal("k1=v1,k2=v2", TracestateUtils.GetString(tracestateEntries));
        }
Example #14
0
        public void MaxEntries()
        {
            var tracestateEntries = new List <KeyValuePair <string, string> >();
            var tracestate        =
                "k0=v,k1=v,k2=v,k3=v,k4=v,k5=v,k6=v,k7=v1,k8=v,k9=v,k10=v,k11=v,k12=v,k13=v,k14=v,k15=v,k16=v,k17=v,k18=v,k19=v,k20=v,k21=v,k22=v,k23=v,k24=v,k25=v,k26=v,k27=v1,k28=v,k29=v,k30=v,k31=v";

            Assert.True(TracestateUtils.AppendTracestate(tracestate, tracestateEntries));
            Assert.Equal(32, tracestateEntries.Count);
            Assert.Equal("k0=v,k1=v,k2=v,k3=v,k4=v,k5=v,k6=v,k7=v1,k8=v,k9=v,k10=v,k11=v,k12=v,k13=v,k14=v,k15=v,k16=v,k17=v,k18=v,k19=v,k20=v,k21=v,k22=v,k23=v,k24=v,k25=v,k26=v,k27=v1,k28=v,k29=v,k30=v,k31=v",
                         TracestateUtils.GetString(tracestateEntries));
        }
Example #15
0
        private static ActivityAndTracestate FromActivity(string spanName, Activity activity)
        {
            List <KeyValuePair <string, string> > tracestate = null;

            if (activity.TraceStateString != null)
            {
                tracestate = new List <KeyValuePair <string, string> >();
                TracestateUtils.AppendTracestate(activity.TraceStateString, tracestate);
            }

            return(new ActivityAndTracestate(activity, tracestate));
        }
Example #16
0
        public void TraceContextFormat_TracestateToStringEmpty()
        {
            var headers = new Dictionary <string, string>
            {
                { TraceParent, $"00-{TraceId}-{SpanId}-01" },
            };

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

            Assert.Empty(ctx.Tracestate);
            Assert.Equal(string.Empty, TracestateUtils.GetString(ctx.Tracestate));
        }
        public void TraceContextFormat_TracestateToStringEmpty()
        {
            var headers = new Dictionary <string, string>
            {
                { "traceparent", "00-abc7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01" },
            };

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

            Assert.Empty(ctx.Tracestate);
            Assert.Equal(string.Empty, TracestateUtils.GetString(ctx.Tracestate));
        }
Example #18
0
        /// <summary>
        /// Creates a <see cref="ILink"/> from Activity.
        /// </summary>
        /// <param name="activity">Activity to create link from.</param>
        /// <returns>New <see cref="ILink"/> instance.</returns>
        public static ILink FromActivity(Activity activity)
        {
            var tracestate        = Tracestate.Empty;
            var tracestateBuilder = Tracestate.Builder;

            if (TracestateUtils.TryExtractTracestate(activity.TraceStateString, tracestateBuilder))
            {
                tracestate = tracestateBuilder.Build();
            }

            return(new Link(
                       SpanContext.Create(activity.TraceId, activity.SpanId, activity.ActivityTraceFlags, tracestate),
                       EmptyAttributes));
        }
Example #19
0
        private static SpanContext ParentContextFromActivity(Activity activity)
        {
            var tracestate        = Tracestate.Empty;
            var tracestateBuilder = Tracestate.Builder;

            if (TracestateUtils.TryExtractTracestate(activity.TraceStateString, tracestateBuilder))
            {
                tracestate = tracestateBuilder.Build();
            }

            return(SpanContext.Create(
                       activity.TraceId,
                       activity.ParentSpanId,
                       ActivityTraceFlags.Recorded,
                       tracestate));
        }
Example #20
0
        private static ActivityAndTracestate FromCurrentParentActivity(string spanName, Activity current)
        {
            var activity = new Activity(spanName);

            activity.SetIdFormat(ActivityIdFormat.W3C);

            activity.Start();
            Activity.Current = current;

            List <KeyValuePair <string, string> > tracestate = null;

            if (activity.TraceStateString != null)
            {
                tracestate = new List <KeyValuePair <string, string> >();
                TracestateUtils.AppendTracestate(activity.TraceStateString, tracestate);
            }

            return(new ActivityAndTracestate(activity, tracestate));
        }
Example #21
0
        private static SpanContext ParentContextFromActivity(Activity activity)
        {
            if (activity.TraceId != default && activity.ParentSpanId != default)
            {
                List <KeyValuePair <string, string> > tracestate = null;

                if (!string.IsNullOrEmpty(activity.TraceStateString))
                {
                    tracestate = new List <KeyValuePair <string, string> >();
                    TracestateUtils.AppendTracestate(activity.TraceStateString, tracestate);
                }

                return(new SpanContext(
                           activity.TraceId,
                           activity.ParentSpanId,
                           ActivityTraceFlags.Recorded,
                           tracestate));
            }

            return(null);
        }
        public void TraceContextFormat_TracestateToString()
        {
            var headers = new Dictionary <string, string>
            {
                { "traceparent", "00-abc7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01" },
                { "tracestate", "k1=v1,k2=v2,k3=v3" },
            };

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

            var entries = ctx.Tracestate.ToArray();

            Assert.Equal(3, entries.Length);
            Assert.Equal("k1", entries[0].Key);
            Assert.Equal("v1", entries[0].Value);
            Assert.Equal("k2", entries[1].Key);
            Assert.Equal("v2", entries[1].Value);
            Assert.Equal("k3", entries[2].Key);
            Assert.Equal("v3", entries[2].Value);

            Assert.Equal("k1=v1,k2=v2,k3=v3", TracestateUtils.GetString(ctx.Tracestate));
        }
Example #23
0
        public void TraceContextFormat_TracestateToString()
        {
            var headers = new Dictionary <string, string>
            {
                { TraceParent, $"00-{TraceId}-{SpanId}-01" },
                { TraceState, "k1=v1,k2=v2,k3=v3" },
            };

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

            var entries = ctx.Tracestate.ToArray();

            Assert.Equal(3, entries.Length);
            Assert.Equal("k1", entries[0].Key);
            Assert.Equal("v1", entries[0].Value);
            Assert.Equal("k2", entries[1].Key);
            Assert.Equal("v2", entries[1].Value);
            Assert.Equal("k3", entries[2].Key);
            Assert.Equal("v3", entries[2].Value);

            Assert.Equal("k1=v1,k2=v2,k3=v3", TracestateUtils.GetString(ctx.Tracestate));
        }
        public void StartSpanFromCurrentActivity()
        {
            var activity = new Activity(SpanName)
                           .SetIdFormat(ActivityIdFormat.W3C)
                           .Start();

            activity.TraceStateString = "k1=v1,k2=v2";

            var span = (Span) new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                       .SetSpanKind(SpanKind.Internal)
                       .SetCreateChild(false)
                       .StartSpan();

            Assert.True(span.Context.IsValid);
            Assert.Equal(activity.TraceId, span.Context.TraceId);
            Assert.Equal(activity.SpanId, span.Context.SpanId);
            Assert.True(((Span)span).ParentSpanId == default);

            Assert.NotNull(Activity.Current);
            Assert.Equal(Activity.Current, activity);
            Assert.Equal("k1=v1,k2=v2", TracestateUtils.GetString(span.Context.Tracestate));

            Assert.Equal(activity.StartTimeUtc, span.StartTimestamp);
        }
        public void StartSpan_CurrentSpanParent()
        {
            var rootSpan = new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                           .SetParent(
                new SpanContext(
                    ActivityTraceId.CreateRandom(),
                    ActivitySpanId.CreateRandom(),
                    ActivityTraceFlags.None,
                    new List <KeyValuePair <string, string> > {
                new KeyValuePair <string, string>("k1", "v1")
            }))
                           .StartSpan();

            using (tracer.WithSpan(rootSpan))
            {
                var childSpan = (Span) new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                                .StartSpan();

                Assert.True(childSpan.Context.IsValid);
                Assert.Equal(rootSpan.Context.TraceId, childSpan.Context.TraceId);
                Assert.Equal(rootSpan.Context.SpanId, childSpan.ParentSpanId);
                Assert.Equal("k1=v1", TracestateUtils.GetString(childSpan.Context.Tracestate));
            }
        }
        public void StartRemoteSpan()
        {
            var spanContext =
                new SpanContext(
                    ActivityTraceId.CreateRandom(),
                    ActivitySpanId.CreateRandom(),
                    ActivityTraceFlags.None,
                    new List <KeyValuePair <string, string> > {
                new KeyValuePair <string, string>("k1", "v1")
            });

            var span = (Span) new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                       .SetSpanKind(SpanKind.Internal)
                       .SetParent(spanContext)
                       .SetRecordEvents(true)
                       .StartSpan();

            Assert.True(span.Context.IsValid);
            Assert.Equal(spanContext.TraceId, span.Context.TraceId);
            Assert.True((span.Context.TraceOptions & ActivityTraceFlags.Recorded) != 0);

            Assert.Equal(spanContext.SpanId, span.ParentSpanId);
            Assert.Equal("k1=v1", TracestateUtils.GetString(span.Context.Tracestate));
        }
Example #27
0
        /// <summary>
        /// Creates a <see cref="ILink"/> from Activity.
        /// </summary>
        /// <param name="activity">Activity to create link from.</param>
        /// <returns>New <see cref="ILink"/> instance.</returns>
        public static ILink FromActivity(Activity activity)
        {
            if (activity == null)
            {
                throw new ArgumentNullException(nameof(activity));
            }

            if (activity.IdFormat != ActivityIdFormat.W3C)
            {
                throw new ArgumentException("Current Activity is not in W3C format");
            }

            var tracestate        = Tracestate.Empty;
            var tracestateBuilder = Tracestate.Builder;

            if (TracestateUtils.TryExtractTracestate(activity.TraceStateString, tracestateBuilder))
            {
                tracestate = tracestateBuilder.Build();
            }

            return(new Link(
                       SpanContext.Create(activity.TraceId, activity.SpanId, activity.ActivityTraceFlags, tracestate),
                       EmptyAttributes));
        }
Example #28
0
        /// <inheritdoc/>
        public ISpan StartSpan()
        {
            var activityForSpan = this.CreateActivityForSpan(this.contextSource, this.parentSpan,
                                                             this.parentSpanContext, this.parentActivity, this.fromActivity);

            if (this.startTimestamp == default)
            {
                this.startTimestamp = new DateTimeOffset(activityForSpan.StartTimeUtc);
            }

            bool sampledIn = MakeSamplingDecision(
                this.parentSpanContext, // it is updated in CreateActivityForSpan
                this.name,
                this.sampler,
                this.links,
                activityForSpan.TraceId,
                activityForSpan.SpanId,
                this.tracerConfiguration);

            if (sampledIn || this.recordEvents)
            {
                activityForSpan.ActivityTraceFlags |= ActivityTraceFlags.Recorded;
            }
            else
            {
                activityForSpan.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded;
            }

            var childTracestate = Enumerable.Empty <KeyValuePair <string, string> >();

            if (this.parentSpanContext != null && this.parentSpanContext.IsValid)
            {
                if (this.parentSpanContext.Tracestate != null &&
                    this.parentSpanContext.Tracestate.Any())
                {
                    childTracestate = this.parentSpanContext.Tracestate;
                }
            }
            else if (activityForSpan.TraceStateString != null)
            {
                var tracestate = new List <KeyValuePair <string, string> >();
                if (TracestateUtils.AppendTracestate(activityForSpan.TraceStateString, tracestate))
                {
                    childTracestate = tracestate;
                }
            }

            var span = new Span(
                activityForSpan,
                childTracestate,
                this.kind,
                this.tracerConfiguration,
                this.spanProcessor,
                this.startTimestamp,
                ownsActivity: this.contextSource != ContextSource.Activity,
                this.libraryResource);

            if (activityForSpan.OperationName != this.name)
            {
                span.UpdateName(this.name);
            }

            LinkSpans(span, this.links);
            return(span);
        }
Example #29
0
        private Activity CreateActivityForSpan(ContextSource contextSource, ISpan explicitParent, SpanContext remoteParent, Activity explicitParentActivity, Activity fromActivity)
        {
            Activity spanActivity        = null;
            Activity originalActivity    = Activity.Current;
            bool     needRestoreOriginal = true;

            switch (contextSource)
            {
            case ContextSource.CurrentActivityParent:
            {
                // Activity will figure out its parent
                spanActivity = new Activity(this.name)
                               .SetIdFormat(ActivityIdFormat.W3C)
                               .Start();

                // chances are, Activity.Current has span attached
                if (CurrentSpanUtils.CurrentSpan is Span currentSpan)
                {
                    this.parentSpanContext = currentSpan.Context;
                }
                else
                {
                    this.parentSpanContext = ParentContextFromActivity(spanActivity);
                }

                break;
            }

            case ContextSource.ExplicitActivityParent:
            {
                spanActivity = new Activity(this.name)
                               .SetParentId(this.parentActivity.TraceId,
                                            this.parentActivity.SpanId,
                                            this.parentActivity.ActivityTraceFlags)
                               .Start();
                spanActivity.TraceStateString = this.parentActivity.TraceStateString;
                this.parentSpanContext        = ParentContextFromActivity(spanActivity);
                break;
            }

            case ContextSource.NoParent:
            {
                spanActivity = new Activity(this.name)
                               .SetIdFormat(ActivityIdFormat.W3C)
                               .SetParentId(" ")
                               .Start();
                this.parentSpanContext = null;
                break;
            }

            case ContextSource.Activity:
            {
                this.parentSpanContext = ParentContextFromActivity(this.fromActivity);
                spanActivity           = this.fromActivity;
                needRestoreOriginal    = false;
                break;
            }

            case ContextSource.ExplicitRemoteParent:
            {
                spanActivity = new Activity(this.name);
                if (this.parentSpanContext != null && this.parentSpanContext.IsValid)
                {
                    spanActivity.SetParentId(this.parentSpanContext.TraceId,
                                             this.parentSpanContext.SpanId,
                                             this.parentSpanContext.TraceOptions);
                    spanActivity.TraceStateString = TracestateUtils.GetString(this.parentSpanContext.Tracestate);
                }

                spanActivity.SetIdFormat(ActivityIdFormat.W3C);
                spanActivity.Start();

                break;
            }

            case ContextSource.ExplicitSpanParent:
            {
                spanActivity = new Activity(this.name);
                if (this.parentSpan.Context.IsValid)
                {
                    spanActivity.SetParentId(this.parentSpan.Context.TraceId,
                                             this.parentSpan.Context.SpanId,
                                             this.parentSpan.Context.TraceOptions);

                    spanActivity.TraceStateString = TracestateUtils.GetString(this.parentSpan.Context.Tracestate);
                }

                spanActivity.SetIdFormat(ActivityIdFormat.W3C);
                spanActivity.Start();

                this.parentSpanContext = this.parentSpan.Context;
                break;
            }

            default:
                throw new ArgumentException($"Unknown parentType {contextSource}");
            }

            if (needRestoreOriginal)
            {
                // Activity Start always puts Activity on top of Current stack
                // in OpenTelemetry we ask users to enable implicit propagation by calling WithSpan
                // it will set Current Activity and attach span to it.
                // we need to work with .NET team to allow starting Activities without updating Current
                // As a workaround here we are undoing updating Current
                Activity.Current = originalActivity;
            }

            return(spanActivity);
        }