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);
        }
Example #2
0
        public ActivityContext Extract <T>(ActivityContext activityContext, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            if (this.defaultContext)
            {
                return(activityContext);
            }

            IEnumerable <string> id = getter(carrier, this.idHeaderName);

            if (id.Count() <= 0)
            {
                return(activityContext);
            }

            var traceparentParsed = TraceContextFormat.TryExtractTraceparent(id.First(), out var traceId, out var spanId, out var traceoptions);

            if (!traceparentParsed)
            {
                return(activityContext);
            }

            string tracestate = string.Empty;
            IEnumerable <string> tracestateCollection = getter(carrier, this.stateHeaderName);

            if (tracestateCollection?.Any() ?? false)
            {
                TraceContextFormat.TryExtractTracestate(tracestateCollection.ToArray(), out tracestate);
            }

            return(new ActivityContext(traceId, spanId, traceoptions, tracestate));
        }
        public void TraceContextFormatCanParseExampleFromSpec()
        {
            Dictionary <string, string> 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, (h, n) => new string[] { h[n] });

            Assert.Equal(TraceId.FromLowerBase16("0af7651916cd43dd8448eb211c80319c"), ctx.TraceId);
            Assert.Equal(SpanId.FromLowerBase16("b9c7c989f97918e1"), ctx.SpanId);
            Assert.True(ctx.TraceOptions.IsSampled);

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

            var first = ctx.Tracestate.Entries.First();

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

            var last = ctx.Tracestate.Entries.Last();

            Assert.Equal("rojo", last.Key);
            Assert.Equal("00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01", last.Value);
        }
Example #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 void TracerBuilder_ValidArgs()
        {
            var builder = new TracerBuilder();

            bool processorFactoryCalled = false;
            bool collectorFactoryCalled = true;

            var sampler      = new ProbabilitySampler(0.1);
            var exporter     = new TestExporter(_ => { });
            var options      = new TracerConfiguration(1, 1, 1);
            var binaryFormat = new BinaryFormat();
            var textFormat   = new TraceContextFormat();

            builder
            .SetSampler(sampler)
            .AddProcessorPipeline(p => p
                                  .SetExporter(exporter)
                                  .SetExportingProcessor(e =>
            {
                processorFactoryCalled = true;
                Assert.Same(e, exporter);
                return(new SimpleSpanProcessor(e));
            }))
            .SetTracerOptions(options)
            .SetBinaryFormat(binaryFormat)
            .SetTextFormat(textFormat)
            .AddCollector(t =>
            {
                Assert.NotNull(t);
                return(new TestCollector(t));
            });

            Assert.Same(sampler, builder.Sampler);

            Assert.NotNull(builder.ProcessingPipelines);
            Assert.Single(builder.ProcessingPipelines);
            Assert.Same(exporter, builder.ProcessingPipelines[0].Exporter);

            Assert.NotNull(builder.ProcessingPipelines[0].Build());
            Assert.True(processorFactoryCalled);

            Assert.Same(options, builder.TracerConfigurationOptions);
            Assert.Same(binaryFormat, builder.BinaryFormat);
            Assert.Same(textFormat, builder.TextFormat);
            Assert.Single(builder.CollectorFactories);

            var collectorFactory = builder.CollectorFactories.Single();

            Assert.Equal(nameof(TestCollector), collectorFactory.Name);
            Assert.Equal("semver:" + typeof(TestCollector).Assembly.GetName().Version, collectorFactory.Version);

            Assert.NotNull(collectorFactory.Factory);
            collectorFactory.Factory(new Tracer(new SimpleSpanProcessor(exporter), new AlwaysSampleSampler(), options, binaryFormat, textFormat,
                                                Resource.Empty));

            Assert.True(collectorFactoryCalled);
        }
Example #6
0
        public void TraceContextFormat_IsBlankIfNoHeader()
        {
            var headers = new Dictionary <string, string>();

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

            Assert.Same(SpanContext.Blank, ctx);
        }
Example #7
0
        public void TraceContextFormat_IsBlankIfNoHeader()
        {
            var headers = new Dictionary <string, string>();

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

            Assert.False(ctx.IsValid);
        }
        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(default, headers, Getter);
Example #9
0
        public void TraceContextFormat_IsBlankIfInvalid()
        {
            var headers = new Dictionary <string, string>
            {
                { "traceparent", "00-xyz7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01" },
            };

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

            Assert.Same(SpanContext.Blank, ctx);
        }
Example #10
0
        public void TraceContextFormat_IsBlankIfNoHeader()
        {
            var headers = new Dictionary <string, string>();

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

            Assert.False(ctx.IsValid());

            // TODO: Validate IsRemote when ActivityContext supports it.
            // Assert.True(ctx.IsRemote);
        }
Example #11
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.NotNull(ctx.TraceState);
        }
Example #12
0
        public void TraceContextFormat_IsBlankIfInvalid()
        {
            var headers = new Dictionary <string, string>
            {
                { TraceParent, $"00-xyz7651916cd43dd8448eb211c80319c-{SpanId}-01" },
            };

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

            Assert.False(ctx.IsValid);
            Assert.True(ctx.IsRemote);
        }
Example #13
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);

            Assert.Equal("k1=v1,k2=v2,k3=v3", 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 #15
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);
        }
Example #16
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);
        }
Example #17
0
        public void TraceContextFormat_Inject_NoTracestate()
        {
            var traceId         = ActivityTraceId.CreateRandom();
            var spanId          = ActivitySpanId.CreateRandom();
            var expectedHeaders = new Dictionary <string, string>
            {
                { TraceParent, $"00-{traceId}-{spanId}-01" },
            };

            var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, traceState: null);
            var carrier         = new Dictionary <string, string>();
            var f = new TraceContextFormat();

            f.Inject(activityContext, carrier, Setter);

            Assert.Equal(expectedHeaders, carrier);
        }
Example #18
0
        public void TraceContextFormat_Inject_WithTracestate()
        {
            var traceId         = ActivityTraceId.CreateRandom();
            var spanId          = ActivitySpanId.CreateRandom();
            var expectedHeaders = new Dictionary <string, string>
            {
                { TraceParent, $"00-{traceId}-{spanId}-01" },
                { TraceState, $"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{traceId}-00f067aa0ba902b7-01" },
            };

            var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, expectedHeaders[TraceState]);
            var carrier         = new Dictionary <string, string>();
            var f = new TraceContextFormat();

            f.Inject(activityContext, carrier, Setter);

            Assert.Equal(expectedHeaders, carrier);
        }
        public void InjectExtract_TextMap_Ok()
        {
            var carrier = new TextMapCarrier();

            var spanContextShim = new SpanContextShim(new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None));

            var format = new TraceContextFormat();

            var tracer = TracerProvider.Default.GetTracer(TracerName);
            var shim   = new TracerShim(tracer, format);

            // first inject
            shim.Inject(spanContextShim, BuiltinFormats.TextMap, carrier);

            // then extract
            var extractedSpanContext = shim.Extract(BuiltinFormats.TextMap, carrier);

            AssertOpenTracerSpanContextEqual(spanContextShim, extractedSpanContext);
        }
Example #20
0
        public void InjectExtract_TextMap_Ok()
        {
            var tracerMock = new Mock <Trace.Tracer>();

            var carrier = new TextMapCarrier();

            var spanContextShim = new SpanContextShim(Defaults.GetOpenTelemetrySpanContext());

            var format = new TraceContextFormat();

            var shim = new TracerShim(tracerMock.Object, format, new BinaryFormat());

            // first inject
            shim.Inject(spanContextShim, BuiltinFormats.TextMap, carrier);

            // then extract
            var extractedSpanContext = shim.Extract(BuiltinFormats.TextMap, carrier);

            AssertOpenTracerSpanContextEqual(spanContextShim, extractedSpanContext);
        }
Example #21
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);

            // TODO: Validate IsRemote when ActivityContext supports it.
            // Assert.True(ctx.IsRemote);
            Assert.True(ctx.IsValid());
            Assert.True((ctx.TraceFlags & ActivityTraceFlags.Recorded) != 0);

            Assert.NotNull(ctx.TraceState);
            Assert.Equal(headers[TraceState], ctx.TraceState);
        }
        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 Extract_Ok()
        {
            var shim = TracerShim.Create(tracer);

            var mockCarrier = new Mock <ITextMap>();

            // The ProxyTracer uses OpenTelemetry.Context.Propagation.TraceContextFormat, so we need to satisfy that.
            var traceContextFormat = new TraceContextFormat();
            var spanContext        = Defaults.GetOpenTelemetrySpanContext();

            var carrierMap = new Dictionary <string, string>();

            // inject the SpanContext into the carrier map
            traceContextFormat.Inject <Dictionary <string, string> >(spanContext, carrierMap, (map, key, value) => map.Add(key, value));

            // send the populated carrier map to the extract method.
            mockCarrier.Setup(x => x.GetEnumerator()).Returns(carrierMap.GetEnumerator());
            var spanContextShim = shim.Extract(BuiltinFormats.TextMap, mockCarrier.Object) as SpanContextShim;

            // Verify that the carrier was called
            mockCarrier.Verify(x => x.GetEnumerator(), Times.Once);

            Assert.Equal(spanContext, spanContextShim.SpanContext);
        }