示例#1
0
        public TracerShim(Trace.Tracer tracer, TextMapPropagator textFormat)
        {
            this.tracer     = tracer ?? throw new ArgumentNullException(nameof(tracer), "Parameter cannot be null");
            this.propagator = textFormat ?? throw new ArgumentNullException(nameof(textFormat), "Parameter cannot be null");

            this.ScopeManager = new ScopeManagerShim(this.tracer);
        }
示例#2
0
        private void TestDefaultPropagatorUsing(Activity a, TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage)
        {
            // Test with non-current
            propagator.Inject(a, null, (object carrier, string fieldName, string value) =>
            {
                if (fieldName == TraceParent && a.IdFormat == ActivityIdFormat.W3C)
                {
                    Assert.Equal(a.Id, value);
                    return;
                }

                if (fieldName == RequestId && a.IdFormat != ActivityIdFormat.W3C)
                {
                    Assert.Equal(a.Id, value);
                    return;
                }

                if (fieldName == TraceState)
                {
                    Assert.Equal(a.TraceStateString, value);
                    return;
                }

                if (fieldName == CorrelationContext)
                {
                    Assert.Equal(GetFormattedBaggage(a.Baggage), value);
                    return;
                }

                Assert.False(true, $"Encountered wrong header name '{fieldName}'");
            });

            TestDefaultExtraction(propagator, a);
            TestBaggageExtraction(propagator, a);
        }
        public void PropagatorStackShouldInjectExtractAllPropagators()
        {
            var ps             = new PropagatorStack(BuiltinFormats.TextMap);
            var httpPropagator = new HttpHeadersPropagator();
            var b3Propagator   = new B3Propagator();
            var textPropagator = new TextMapPropagator();

            ps.AddPropagator(httpPropagator);
            ps.AddPropagator(b3Propagator);
            ps.AddPropagator(textPropagator);

            var carrier = new Dictionary <string, string>();
            var context = new SpanContext(0, 0);

            ps.Inject(context, BuiltinFormats.TextMap, new TextMapInjectAdapter(carrier));

            var propagators = new List <IPropagator> {
                httpPropagator, b3Propagator, textPropagator
            };

            foreach (var t in propagators)
            {
                var extractedContext =
                    t.Extract(BuiltinFormats.TextMap, new TextMapExtractAdapter(carrier));
                Assert.NotNull(extractedContext);
                Assert.Equal(context.TraceId, extractedContext.TraceId);
                Assert.Equal(context.SpanId, extractedContext.SpanId);
            }
        }
        public void TextHeaderPropagatorIsCaseSensitive(CasingType casingType)
        {
            UInt64 spanId  = 4952807665017200957;
            UInt64 traceId = 14848807816610383171;

            var headers = new Dictionary <string, string>
            {
                { ToCase("Ot-Tracer-Spanid", casingType), spanId.ToString("X") },
                { ToCase("Ot-Tracer-Traceid", casingType), traceId.ToString("X") },
            };

            var textPropagator   = new TextMapPropagator();
            var extractedContext =
                textPropagator.Extract(BuiltinFormats.TextMap,
                                       new TextMapExtractAdapter(headers));

            if (casingType != CasingType.LowerCase)
            {
                Assert.Null(extractedContext);
                return;
            }

            Assert.NotNull(extractedContext);
            Assert.Equal(spanId.ToString("x"), extractedContext.SpanId);
            Assert.Equal(traceId.ToString("x"), extractedContext.TraceId);
        }
示例#5
0
        private void TestPassThroughPropagatorUsingW3CActivity(TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage)
        {
            using Activity a = CreateW3CActivity("PassThroughW3C", "PassThroughW3CState=1", baggage);

            propagator.Inject(a, null, (object carrier, string fieldName, string value) =>
            {
                if (fieldName == TraceParent)
                {
                    Assert.Equal(a.Id, value);
                    return;
                }

                if (fieldName == TraceState)
                {
                    Assert.Equal(a.TraceStateString, value);
                    return;
                }

                if (fieldName == CorrelationContext)
                {
                    Assert.Equal(GetFormattedBaggage(a.Baggage), value);
                    return;
                }

                Assert.False(true, $"Encountered wrong header name '{fieldName}'");
            });

            TestDefaultExtraction(propagator, a);
            TestBaggageExtraction(propagator, a);
        }
示例#6
0
        public PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            if (this.defaultContext)
            {
                return(context);
            }

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

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

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

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

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

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

            return(new PropagationContext(
                       new ActivityContext(traceId, spanId, traceoptions, tracestate),
                       context.Baggage));
        }
示例#7
0
 private void TestFields(TextMapPropagator propagator)
 {
     Assert.True(propagator.Fields.Contains(TraceParent));
     Assert.True(propagator.Fields.Contains(RequestId));
     Assert.True(propagator.Fields.Contains(TraceState));
     Assert.True(propagator.Fields.Contains(Baggage));
     Assert.True(propagator.Fields.Contains(CorrelationContext));
 }
        public TracerShim(Trace.Tracer tracer, TextMapPropagator textFormat)
        {
            Guard.ThrowIfNull(tracer);
            Guard.ThrowIfNull(textFormat);

            this.tracer       = tracer;
            this.propagator   = textFormat;
            this.ScopeManager = new ScopeManagerShim(this.tracer);
        }
示例#9
0
        public void TextMapPropagator_Extract_ThrowsWhenCarrierIsNotITextMap()
        {
            var propagator  = new TextMapPropagator(new HeadersConfig("", ""), (val) => val, (val) => val);
            var spanContext = Substitute.For <ILetsTraceSpanContext>();

            var ex = Assert.Throws <ArgumentException>(() => propagator.Extract(new List <string>()));

            Assert.Equal("carrier is not ITextMap", ex.Message);
        }
        public void CanParseExampleFromSpec()
        {
            var headers = new Dictionary <string, string>
            {
                { TraceParent, $"00-{TraceId}-{SpanId}-01" },
                { TraceState, $"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01" },
            };

            var f   = new TextMapPropagator();
            var ctx = f.Extract(default, headers, Getter);
示例#11
0
        public void TextMapPropagator_Extract_TraceContextHeaderMissing()
        {
            var headersConfig = new HeadersConfig("TraceContextHeaderName", "TraceBaggageHeaderPrefix");
            var propagator    = new TextMapPropagator(headersConfig, (val) => val, (val) => val);
            var carrier       = new DictionaryTextMap(new Dictionary <string, string> {
                { "TraceBaggageHeaderPrefix-Item1", "item1" },
                { "TraceBaggageHeaderPrefix-Item2", "item2" },
            });

            var sc = (SpanContext)propagator.Extract(carrier);

            Assert.Null(sc);
        }
示例#12
0
        private void TestNoOutputPropagatorUsingW3CActivity(TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage)
        {
            using Activity a = CreateW3CActivity("NoOutputW3C", state, baggage);

            propagator.Inject(a, null, (object carrier, string fieldName, string value) =>
            {
                Assert.False(true, $"Not expected to have the setter callback be called in the NoOutput propgator.");
            });

            TestDefaultExtraction(propagator, a);

            TestBaggageExtraction(propagator, a);
        }
示例#13
0
        private void TestDefaultPropagatorUsingHierarchicalActivity(TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage)
        {
            using Activity a = CreateHierarchicalActivity("LegacyHierarchical1", null, "LegacyHierarchicalState=1", baggage);
            using Activity b = CreateHierarchicalActivity("LegacyHierarchical2", null, "LegacyHierarchicalState=2", baggage);

            Assert.NotSame(Activity.Current, a);

            TestDefaultPropagatorUsing(a, propagator, state, baggage);

            Assert.Same(Activity.Current, b);

            TestDefaultPropagatorUsing(Activity.Current, propagator, state, baggage);
        }
        public WorkerBackgroundService(
            ILogger <WorkerBackgroundService> logger,
            IConfiguration configuration,
            ConnectionFactory connectionFactory)
        {
            _logger            = logger;
            _configuration     = configuration;
            _connectionFactory = connectionFactory;

            _rabbitConnection = _connectionFactory.CreateConnection();
            _rabbitChanel     = _rabbitConnection.CreateModel();
            _propagator       = new TraceContextPropagator();
        }
示例#15
0
        private void TestDefaultExtraction(TextMapPropagator propagator, Activity a)
        {
            bool traceParentEncountered = false;

            propagator.ExtractTraceIdAndState(null, (object carrier, string fieldName, out string?fieldValue, out IEnumerable <string>?fieldValues) =>
            {
                Assert.Null(carrier);
                fieldValues = null;
                fieldValue  = null;

                if (fieldName == TraceParent)
                {
                    if (a.IdFormat == ActivityIdFormat.W3C)
                    {
                        fieldValue = a.Id;
                    }
                    else
                    {
                        traceParentEncountered = true;
                    }
                    return;
                }

                if (fieldName == RequestId)
                {
                    if (a.IdFormat == ActivityIdFormat.W3C)
                    {
                        Assert.True(false, $"Not expected to get RequestId as we expect the request handled using TraceParenet.");
                    }
                    else
                    {
                        Assert.True(traceParentEncountered, $"Expected to get TraceParent request before getting RequestId.");
                        fieldValue = a.Id;
                    }

                    return;
                }

                if (fieldName == TraceState)
                {
                    fieldValue = a.TraceStateString;
                    return;
                }

                Assert.False(true, $"Encountered wrong header name '{fieldName}'");
            }, out string?traceId, out string?traceState);

            Assert.Equal(a.Id, traceId);
            Assert.Equal(a.TraceStateString, traceState);
        }
示例#16
0
        private void TestPassThroughPropagatorUsingHierarchicalActivityWithParentId(TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage)
        {
            using Activity a = CreateHierarchicalActivity("PassThrough", "Parent1", state, baggage);
            using Activity b = CreateHierarchicalActivity("PassThroughChild1", "Parent2", state + "1", new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("Child1Key", "Child1Value")
            });
            using Activity c = CreateHierarchicalActivity("PassThroughChild2", "Parent3", state + "2", new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("Child2Key", "Child2Value")
            });

            propagator.Inject(a, null, (object carrier, string fieldName, string value) =>
            {
                if (fieldName == TraceParent)
                {
                    Assert.False(true, $"Unexpected to inject a TraceParent with Hierarchical Activity.");
                    return;
                }

                if (fieldName == RequestId)
                {
                    Assert.Equal(c.ParentId, value);
                    return;
                }

                if (fieldName == TraceState)
                {
                    Assert.Equal(c.TraceStateString, value);
                    return;
                }

                if (fieldName == CorrelationContext)
                {
                    Assert.Equal(GetFormattedBaggage(c.Baggage), value);
                    return;
                }

                Assert.False(true, $"Encountered wrong header name '{fieldName}'");
            });

            TestDefaultExtraction(propagator, a);
            TestDefaultExtraction(propagator, b);
            TestDefaultExtraction(propagator, c);

            TestBaggageExtraction(propagator, a);
            TestBaggageExtraction(propagator, b);
            TestBaggageExtraction(propagator, c);
        }
示例#17
0
        public void InjectExtract_TextMap_Ok()
        {
            var carrier = new TextMapCarrier();

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

            var format = new TextMapPropagator();

            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);
        }
示例#18
0
        public void TextMapPropagator_Inject_SetsTheRightHeadersWithTheRightData()
        {
            var headersConfig = new HeadersConfig("TraceContextHeaderName", "TraceBaggageHeaderPrefix");
            var propagator    = new TextMapPropagator(headersConfig, (val) => val, (val) => val);
            var baggage       = new Dictionary <string, string> {
                { "key1", "value1" }, { "key2", "value2" }
            };
            var spanContext = Substitute.For <ILetsTraceSpanContext>();
            var carrier     = new DictionaryTextMap();

            spanContext.GetBaggageItems().Returns(baggage);

            propagator.Inject(spanContext, carrier);

            var carrierDict = carrier.ToDictionary(c => c.Key, c => c.Value);

            Assert.Equal(spanContext.GetType().FullName, carrierDict[headersConfig.TraceContextHeaderName]); // cannot mock ToString
            Assert.Equal(baggage["key1"], carrierDict[$"{headersConfig.TraceBaggageHeaderPrefix}-key1"]);
            Assert.Equal(baggage["key2"], carrierDict[$"{headersConfig.TraceBaggageHeaderPrefix}-key2"]);
        }
示例#19
0
        public void TextMapPropagator_Extract_SetsTheRightHeadersWithTheRightData()
        {
            var headersConfig = new HeadersConfig("TraceContextHeaderName", "TraceBaggageHeaderPrefix");
            var propagator    = new TextMapPropagator(headersConfig, (val) => val, (val) => val);
            var carrier       = new DictionaryTextMap(new Dictionary <string, string> {
                { "TraceContextHeaderName", "1:2:3:4" },
                { "TraceBaggageHeaderPrefix-Item1", "item1" },
                { "TraceBaggageHeaderPrefix-Item2", "item2" },
            });

            var sc = (SpanContext)propagator.Extract(carrier);

            var baggage = sc.GetBaggageItems().ToDictionary(kv => kv.Key, kv => kv.Value);

            Assert.Equal("item1", baggage["Item1"]);
            Assert.Equal("item2", baggage["Item2"]);
            Assert.Equal("1", sc.TraceId.Low.ToString());
            Assert.Equal("2", sc.SpanId.ToString());
            Assert.Equal("3", sc.ParentId.ToString());
            Assert.Equal(4, (byte)sc.Flags);
        }
示例#20
0
        private void TestPassThroughPropagatorWithNullCurrent(TextMapPropagator propagator)
        {
            Activity.Current = null;

            propagator.Inject(null, null, (object carrier, string fieldName, string value) =>
            {
                Assert.False(true, $"PassThroughPropagator shouldn't inject anything if the Activity.Current is null");
            });

            using Activity a = CreateW3CActivity("PassThroughNotNull", "", null);

            propagator.Inject(a, null, (object carrier, string fieldName, string value) =>
            {
                if (fieldName == TraceParent)
                {
                    Assert.Equal(a.Id, value);
                    return;
                }

                Assert.False(true, $"Encountered wrong header name '{fieldName}'");
            });
        }
示例#21
0
        private void TestBaggageExtraction(TextMapPropagator propagator, Activity a)
        {
            bool baggageEncountered = false;

            IEnumerable <KeyValuePair <string, string?> >?b = propagator.ExtractBaggage(null, (object carrier, string fieldName, out string?fieldValue, out IEnumerable <string>?fieldValues) =>
            {
                Assert.Null(carrier);
                fieldValue  = null;
                fieldValues = null;

                if (fieldName == Baggage)
                {
                    if (a.IdFormat == ActivityIdFormat.W3C)
                    {
                        fieldValue = GetFormattedBaggage(a.Baggage);
                    }
                    else
                    {
                        baggageEncountered = true;
                    }

                    return;
                }

                if (fieldName == CorrelationContext && a.IdFormat != ActivityIdFormat.W3C)
                {
                    Assert.True(baggageEncountered, $"Expected to get Baggage request before getting Correlation-Context.");
                    fieldValue = GetFormattedBaggage(a.Baggage);
                    return;
                }

                Assert.False(true, $"Encountered wrong header name '{fieldName}'");
            });

            Assert.Equal(GetFormattedBaggage(a.Baggage, false, true), GetFormattedBaggage(b, true));
        }
示例#22
0
        /// <summary>
        /// Creates root (first level) activity that describes incoming request.
        /// </summary>
        /// <param name="textMapPropagator"><see cref="TextMapPropagator"/>.</param>
        /// <param name="context"><see cref="HttpContext"/>.</param>
        /// <param name="onRequestStartedCallback">Callback action.</param>
        /// <returns>New root activity.</returns>
        public static Activity StartAspNetActivity(TextMapPropagator textMapPropagator, HttpContext context, Action <Activity, HttpContext> onRequestStartedCallback)
        {
            Debug.Assert(context != null, "Context is null.");

            PropagationContext propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter);
示例#23
0
 internal static void Reset()
 {
     DefaultTextMapPropagator = Noop;
 }
示例#24
0
        public void TestAllPropagators()
        {
            RemoteExecutor.Invoke(() => {
                Assert.NotNull(TextMapPropagator.Current);

                //
                // Default Propagator
                //

                Assert.Same(TextMapPropagator.CreateDefaultPropagator(), TextMapPropagator.Current);

                TestDefaultPropagatorUsingW3CActivity(
                    TextMapPropagator.Current,
                    "Legacy1=true",
                    new List <KeyValuePair <string, string> >()
                {
                    new KeyValuePair <string, string>("     LegacyKey1     ", "    LegacyValue1    ")
                });

                TestDefaultPropagatorUsingHierarchicalActivity(
                    TextMapPropagator.Current,
                    "Legacy2=true",
                    new List <KeyValuePair <string, string> >()
                {
                    new KeyValuePair <string, string>("LegacyKey2", "LegacyValue2")
                });

                TestFields(TextMapPropagator.Current);

                //
                // NoOutput Propagator
                //

                TextMapPropagator.Current = TextMapPropagator.CreateNoOutputPropagator();
                Assert.NotNull(TextMapPropagator.Current);
                TestNoOutputPropagatorUsingHierarchicalActivity(
                    TextMapPropagator.Current,
                    "ActivityState=1",
                    new List <KeyValuePair <string, string> >()
                {
                    new KeyValuePair <string, string>("B1", "V1"), new KeyValuePair <string, string>(" B2 ", " V2 ")
                });

                TestNoOutputPropagatorUsingHierarchicalActivity(
                    TextMapPropagator.Current,
                    "ActivityState=2",
                    null);

                TestNoOutputPropagatorUsingW3CActivity(
                    TextMapPropagator.Current,
                    "ActivityState=1",
                    new List <KeyValuePair <string, string> >()
                {
                    new KeyValuePair <string, string>(" B3 ", " V3"), new KeyValuePair <string, string>(" B4 ", " V4 "), new KeyValuePair <string, string>("B5", "V5")
                });

                TestNoOutputPropagatorUsingW3CActivity(
                    TextMapPropagator.Current,
                    "ActivityState=2",
                    null);

                TestFields(TextMapPropagator.Current);

                //
                // Pass Through Propagator
                //

                TextMapPropagator.Current = TextMapPropagator.CreatePassThroughPropagator();
                Assert.NotNull(TextMapPropagator.Current);
                TestPassThroughPropagatorUsingHierarchicalActivityWithParentChain(
                    TextMapPropagator.Current,
                    "PassThrough=true",
                    new List <KeyValuePair <string, string> >()
                {
                    new KeyValuePair <string, string>("PassThroughKey1", "PassThroughValue1"), new KeyValuePair <string, string>("PassThroughKey2", "PassThroughValue2")
                });

                TestPassThroughPropagatorUsingHierarchicalActivityWithParentId(
                    TextMapPropagator.Current,
                    "PassThrough1=true",
                    new List <KeyValuePair <string, string> >()
                {
                    new KeyValuePair <string, string>("PassThroughKey3", "PassThroughValue3"), new KeyValuePair <string, string>(" PassThroughKey4 ", " PassThroughValue4 ")
                });

                TestPassThroughPropagatorUsingW3CActivity(
                    TextMapPropagator.Current,
                    "PassThrough2=1",
                    new List <KeyValuePair <string, string> >()
                {
                    new KeyValuePair <string, string>("     PassThroughKey4     ", "    PassThroughValue4    ")
                });

                TestPassThroughPropagatorWithNullCurrent(TextMapPropagator.Current);

                TestFields(TextMapPropagator.Current);

                //
                // Test Current
                //

                Assert.Throws <ArgumentNullException>(() => TextMapPropagator.Current = null);
            }).Dispose();
        }
示例#25
0
 /// <summary>
 /// Sets the Default TextMapPropagator.
 /// </summary>
 /// <param name="textMapPropagator">TextMapPropagator to be set as default.</param>
 public static void SetDefaultTextMapPropagator(TextMapPropagator textMapPropagator)
 {
     Propagators.DefaultTextMapPropagator = textMapPropagator;
 }