Пример #1
0
 public void TryParseFailsForInvalidStrings()
 {
     Assert.False(TraceId.TryParse(null, out var _));
     Assert.False(TraceId.TryParse(string.Empty, out var _));
     Assert.False(TraceId.TryParse("a string", out var _));
     Assert.False(TraceId.TryParse("489df891urfd", out var _));
 }
        public SpanContext Extract(ITextMap carrier)
        {
            var        traceId  = default(TraceId);
            long       spanId   = 0;
            long?      parentId = null;
            var        debug    = false;
            var        sampled  = false;
            const bool shared   = false;

            foreach (var entry in carrier)
            {
                switch (entry.Key)
                {
                case B3TraceId:
                    if (!TraceId.TryParse(entry.Value, out traceId))
                    {
                        throw new ZipkinFormatException(
                                  $"TraceId in format [{entry.Value}] is incompatible. Please use an X16 encoded 128bit or 64bit id.");
                    }
                    break;

                case B3SpanId:
                    if (!long.TryParse(entry.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture,
                                       out spanId))
                    {
                        throw new ZipkinFormatException(
                                  $"SpanId in format [{entry.Value}] is incompatible. Please use an X16 encoded 64bit id.");
                    }
                    break;

                case B3ParentId:
                    if (!long.TryParse(entry.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture,
                                       out var p))
                    {
                        throw new ZipkinFormatException(
                                  $"ParentId in format [{entry.Value}] is incompatible. Please use an X16 encoded 64bit id.");
                    }
                    parentId = p;
                    break;

                case B3Debug:
                    if (entry.Value.Equals("1"))
                    {
                        debug = true;
                    }
                    break;

                case B3Sampled:
                    if (entry.Value.Equals("1"))
                    {
                        sampled = true;
                    }
                    break;
                }
            }

            return(new SpanContext(traceId, spanId, parentId?.ToString("x16"), debug, sampled, shared));
        }
Пример #3
0
        public Property ShouldParse64BitTraceIds(long traceIdLow)
        {
            var traceId1 = new TraceId(traceIdLow);
            var parsed   = TraceId.TryParse(traceId1.ToString(), out var traceId2);

            return(parsed.Label($"Should have been able to parse {traceId1}")
                   .And(traceId2.Equals(traceId1)
                        .Label("Expected a trace parsed from an original trace to be equal to the original")));
        }
Пример #4
0
        public SpanContext Extract(IPropagatorMap propagatorMap)
        {
            if (propagatorMap == null)
            {
                throw new ArgumentNullException(nameof(propagatorMap));
            }

            TraceId?traceId = null;
            ulong?  spanId = null, parentId = null;
            bool    sampled = false, debug = false;;

            foreach (var entry in propagatorMap)
            {
                if (string.Equals(entry.Key, TraceIdHeader, StringComparison.OrdinalIgnoreCase))
                {
                    if (TraceId.TryParse(entry.Value, out var _trace))
                    {
                        traceId = _trace;
                    }
                }
                else if (string.Equals(entry.Key, SpanIdHeader, StringComparison.OrdinalIgnoreCase))
                {
                    if (ulong.TryParse(entry.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var _spanId))
                    {
                        spanId = _spanId;
                    }
                }
                else if (string.Equals(entry.Key, ParentIdHeader, StringComparison.OrdinalIgnoreCase))
                {
                    if (ulong.TryParse(entry.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var _parent))
                    {
                        parentId = _parent;
                    }
                }
                else if (string.Equals(entry.Key, SampledHeader, StringComparison.OrdinalIgnoreCase))
                {
                    sampled = string.Equals(entry.Value, SampledTrue);
                }
                else if (string.Equals(entry.Key, DebugHeader, StringComparison.OrdinalIgnoreCase))
                {
                    debug = string.Equals(entry.Value, SampledTrue);
                }
            }
            if (traceId == null || spanId == null)
            {
                return(null);
            }
            return(new SpanContext(traceId.Value,
                                   spanId.Value,
                                   parentId,
                                   sampled,
                                   debug,
                                   shared: false));
        }
Пример #5
0
 public void TryParseParses32bitHexStringCorrectly(string toParse, ulong traceIdHigh, ulong traceIdLow)
 {
     Assert.True(TraceId.TryParse(toParse, out var actual));
     Assert.True(actual.Is128Bit);
     Assert.Equal(actual, new TraceId(traceIdHigh, traceIdLow));
 }
Пример #6
0
 public void TryParseParses16bitHexStringCorrectly(string toParse, ulong expected)
 {
     Assert.True(TraceId.TryParse(toParse, out var actual));
     Assert.False(actual.Is128Bit);
     Assert.Equal(actual.TraceIdLow, expected);
 }
Пример #7
0
        public SpanContext Extract(ITextMap carrier)
        {
            // try to extract the single B3 propagation value instead
            var single = _singleHeaderPropagator.Extract(carrier);

            if (single != null)
            {
                return(single);
            }

            TraceId?   traceId  = null;
            string     spanId   = null;
            string     parentId = null;
            var        debug    = false;
            var        sampled  = false;
            const bool shared   = false;

            foreach (var entry in carrier)
            {
                switch (entry.Key.ToLowerInvariant())
                {
                case B3TraceId:
                    if (!TraceId.TryParse(entry.Value, out var t))
                    {
                        throw new ZipkinFormatException(
                                  $"TraceId in format [{entry.Value}] is incompatible. Please use an X16 encoded 128bit or 64bit id.");
                    }
                    traceId = t;
                    break;

                case B3SpanId:
                    spanId = entry.Value;
                    break;

                case B3ParentId:
                    parentId = entry.Value;
                    break;

                case B3Debug:
                    if (entry.Value.Equals("1"))
                    {
                        debug = true;
                    }
                    break;

                case B3Sampled:
                    if (entry.Value.Equals("1") || entry.Value.ToLowerInvariant().Equals("true")
                        ) // support older tracers https://github.com/petabridge/Petabridge.Tracing.Zipkin/issues/72
                    {
                        sampled = true;
                    }
                    break;
                }
            }

            if (traceId != null && spanId != null) // don't care of ParentId is null or not
            {
                return(new SpanContext(traceId.Value, spanId, parentId, debug, sampled, shared));
            }
            return(null);
        }
        private static SpanContext ParseB3SingleFormat(char[] b3, int begin, int count)
        {
            if (count == 0)
            {
                return(null);
            }

            var pos = begin;

            if (pos + 1 == count) // sampling flags only
            {
                return(null);
            }

            // At this point we expect at least a traceid-spanid pair
            if (count < 16 + 1 + 16)
            {
                throw new ArgumentOutOfRangeException(nameof(b3), $"Invalid input: truncated {new string(b3)}");
            }
            if (count > FORMAT_MAX_LENGTH)
            {
                throw new ArgumentOutOfRangeException(nameof(b3), $"Invalid input: too long {new string(b3)}");
            }

            string traceId = null;

            if (b3[pos + 32] == '-')
            {
                traceId = new string(b3, pos, 32);
                pos    += 32;
            }
            else
            {
                traceId = new string(b3, 0, 16);
                pos    += 16;
            }

            TraceId trace;

            if (!TraceId.TryParse(traceId, out trace))
            {
                throw new ArgumentOutOfRangeException("traceId",
                                                      $"Invalid input: expected a 16 or 32 lower hex trace ID at offset 0 [{traceId}]");
            }

            if (!CheckHyphen(b3, pos++))
            {
                return(null);
            }

            if (pos + 16 > count)
            {
                throw new ArgumentOutOfRangeException("spanId",
                                                      $"Invalid input: expected a 16 span id at offset {pos}");
            }

            var spanId = new string(b3, pos, 16);

            pos += 16; // spanid

            var    sampled  = false;
            var    debug    = false;
            string parentId = null;

            if (count > pos)          // sampling flags or debug
            {
                if (count == pos + 1) // sampling flag didn't get included
                {
                    throw new ArgumentOutOfRangeException(nameof(b3), "Invalid input: truncated");
                }

                if (!CheckHyphen(b3, pos++))
                {
                    return(null);
                }

                if (CheckHyphen(b3, pos + 1) || pos + 1 == count)
                {
                    var sampledField = b3[pos];
                    switch (sampledField)
                    {
                    case 'd':
                        debug = true;
                        break;

                    case '1':
                        sampled = true;
                        break;

                    case '0':
                        sampled = false;
                        break;

                    default:
                        break;
                    }

                    pos++; // need to account for the flag
                    if (!CheckHyphen(b3, pos++))
                    {
                        return(new SpanContext(trace, spanId, null, debug, sampled));
                    }
                }


                if (count > pos)
                {
                    //If we've made it here, there should be a parentId
                    if (pos + 16 > count)
                    {
                        throw new ArgumentOutOfRangeException("parentId",
                                                              $"Invalid input: expected a 16 parent id at offset {pos}");
                    }
                    parentId = new string(b3, pos, 16);
                }
            }

            return(new SpanContext(trace, spanId, parentId, debug, sampled));
        }