public ISpanContext Extract(ITextMap carrier)
        {
            SpanContext spanContext             = null;
            Dictionary <string, string> baggage = new Dictionary <string, string>();

            foreach (var item in carrier)
            {
                if (item.Key.ToLower() == _spanContextKey.ToLower())
                {
                    spanContext = SpanContext.FromString(item.Value);
                }

                baggage.Add(item.Key, item.Value);
            }

            if (spanContext is null)
            {
                return(null);
            }

            if (baggage.Any())
            {
                spanContext = spanContext.WithBaggage(baggage);
            }

            return(spanContext);
        }
예제 #2
0
        public ISpanContext Extract <TCarrier>(TCarrier carrier)
        {
            if (carrier is ITextMap map)
            {
                var         baggage = new Dictionary <string, string>();
                SpanContext context = null;

                foreach (var item in map)
                {
                    // GRPC Metadata is case insensitive, so the case could get lost.
                    if (item.Key.Equals(_headersConfig.TraceContextHeaderName, StringComparison.OrdinalIgnoreCase))
                    {
                        var safeValue = _decodeValue(item.Value);
                        context = SpanContext.FromString(safeValue);
                    }
                    else if (item.Key.StartsWith(_headersConfig.TraceBaggageHeaderPrefix, StringComparison.OrdinalIgnoreCase))
                    {
                        var safeKey   = RemoveBaggageKeyPrefix(item.Key);
                        var safeValue = _decodeValue(item.Value);
                        baggage.Add(safeKey, safeValue);
                    }
                }

                return(context?.SetBaggageItems(baggage));
            }
            throw new ArgumentException($"{nameof(carrier)} is not ITextMap");
        }
예제 #3
0
        public void SpanContext_FromString()
        {
            var ex = Assert.Throws <Exception>(() => SpanContext.FromString(""));

            Assert.Equal("Cannot convert empty string to SpanContext", ex.Message);

            ex = Assert.Throws <Exception>(() => SpanContext.FromString("abcd"));
            Assert.Equal("String does not match tracer state format", ex.Message);

            ex = Assert.Throws <Exception>(() => SpanContext.FromString("x:1:1:1"));
            Assert.Equal("Cannot parse Low TraceId from string: x", ex.Message);

            ex = Assert.Throws <Exception>(() => SpanContext.FromString("1:x:1:1"));
            Assert.Equal("Cannot parse SpanId from string: x", ex.Message);

            ex = Assert.Throws <Exception>(() => SpanContext.FromString("1:1:x:1"));
            Assert.Equal("Cannot parse SpanId from string: x", ex.Message);

            var tooLongTraceId = "0123456789abcdef0123456789abcdef012";

            ex = Assert.Throws <Exception>(() => SpanContext.FromString($"{tooLongTraceId}:1:1:2"));
            Assert.Equal($"TraceId cannot be longer than 32 hex characters: {tooLongTraceId}", ex.Message);

            var justRightTraceId = "0123456789abcdeffedcba9876543210";
            var sc = SpanContext.FromString($"{justRightTraceId}:1:1:2");

            Assert.Equal("0123456789abcdef", sc.TraceId.High.ToString("x016"));
            Assert.Equal("fedcba9876543210", sc.TraceId.Low.ToString("x016"));

            var badHighTraceId = "01234_6789abcdeffedcba9876543210";

            ex = Assert.Throws <Exception>(() => SpanContext.FromString($"{badHighTraceId}:1:1:2"));
            Assert.Equal("Cannot parse High TraceId from string: 01234_6789abcdef", ex.Message);

            var badLowTraceId = "0123456789abcdeffedcba_876543210";

            ex = Assert.Throws <Exception>(() => SpanContext.FromString($"{badLowTraceId}:1:1:2"));
            Assert.Equal("Cannot parse Low TraceId from string: fedcba_876543210", ex.Message);

            var validSpanId = "0123456789abcdef";

            sc = SpanContext.FromString($"1:{validSpanId}:1:2");
            Assert.Equal("123456789abcdef", sc.SpanId.ToString());

            var badSpanId = "0123456789abcdef0";

            ex = Assert.Throws <Exception>(() => SpanContext.FromString($"1:{badSpanId}:1:2"));
            Assert.Equal($"SpanId cannot be longer than 16 hex characters: {badSpanId}", ex.Message);

            sc = SpanContext.FromString("10000000000000001:1:1:2");
            Assert.Equal("1", sc.TraceId.High.ToString());
            Assert.Equal("1", sc.TraceId.Low.ToString());
            Assert.Equal((ContextFlags)2, sc.Flags);

            sc = SpanContext.FromString("1:1:1:1");
            Assert.Equal("0", sc.TraceId.High.ToString());
            Assert.Equal("1", sc.TraceId.Low.ToString());
            Assert.Equal("1", sc.SpanId.ToString());
            Assert.Equal("1", sc.SpanId.ToString());
            Assert.Equal(ContextFlags.Sampled, sc.Flags);
        }