Beispiel #1
0
        private ISpan StartSpanInternal(
            ISpanContext parent,
            bool hasRemoteParent,
            string name,
            ISampler sampler,
            IEnumerable <ISpan> parentLinks,
            bool recordEvents,
            Timer timestampConverter)
        {
            ITraceParams        activeTraceParams = this.Options.TraceConfig.ActiveTraceParams;
            IRandomGenerator    random            = this.Options.RandomHandler;
            ITraceId            traceId;
            ISpanId             spanId       = SpanId.GenerateRandomId(random);
            ISpanId             parentSpanId = null;
            TraceOptionsBuilder traceOptionsBuilder;

            if (parent == null || !parent.IsValid)
            {
                // New root span.
                traceId             = TraceId.GenerateRandomId(random);
                traceOptionsBuilder = TraceOptions.Builder();

                // This is a root span so no remote or local parent.
                // hasRemoteParent = null;
                hasRemoteParent = false;
            }
            else
            {
                // New child span.
                traceId             = parent.TraceId;
                parentSpanId        = parent.SpanId;
                traceOptionsBuilder = TraceOptions.Builder(parent.TraceOptions);
            }

            traceOptionsBuilder.SetIsSampled(
                MakeSamplingDecision(
                    parent,
                    hasRemoteParent,
                    name,
                    sampler,
                    parentLinks,
                    traceId,
                    spanId,
                    activeTraceParams));
            TraceOptions traceOptions = traceOptionsBuilder.Build();
            SpanOptions  spanOptions  = SpanOptions.None;

            if (traceOptions.IsSampled || recordEvents)
            {
                spanOptions = SpanOptions.RecordEvents;
            }

            ISpan span = Span.StartSpan(
                SpanContext.Create(traceId, spanId, traceOptions, parent?.Tracestate ?? Tracestate.Empty),
                spanOptions,
                name,
                parentSpanId,
                hasRemoteParent,
                activeTraceParams,
                this.Options.StartEndHandler,
                timestampConverter);

            LinkSpans(span, parentLinks);
            span.Kind = this.Kind;
            return(span);
        }
Beispiel #2
0
        private bool TryExtractTraceparent(string traceparent, out ITraceId traceId, out ISpanId spanId, out TraceOptions traceoptions)
        {
            // from https://github.com/w3c/distributed-tracing/blob/master/trace_context/HTTP_HEADER_FORMAT.md
            // traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01

            traceId      = TraceId.Invalid;
            spanId       = SpanId.Invalid;
            traceoptions = TraceOptions.Default;
            var bestAttempt = false;

            if (string.IsNullOrWhiteSpace(traceparent))
            {
                return(false);
            }

            // if version does not end with delimeter
            if (traceparent.Length < VersionPrefixIdLength || traceparent[VersionPrefixIdLength - 1] != '-')
            {
                return(false);
            }

            // or version is not a hex (will throw)
            var versionArray = Arrays.StringToByteArray(traceparent, 0, VersionLength);

            if (versionArray[0] == 255)
            {
                return(false);
            }

            if (versionArray[0] > 0)
            {
                // expected version is 00
                // for higher versions - best attempt parsing of trace id, span id, etc.
                bestAttempt = true;
            }

            if (traceparent.Length < VersionAndTraceIdLength || traceparent[VersionAndTraceIdLength - 1] != '-')
            {
                return(false);
            }

            try
            {
                traceId = TraceId.FromBytes(Arrays.StringToByteArray(traceparent, VersionPrefixIdLength, TraceIdLength));
            }
            catch (ArgumentOutOfRangeException)
            {
                // it's ok to still parse tracestate
                return(false);
            }

            if (traceparent.Length < VersionAndTraceIdAndSpanIdLength || traceparent[VersionAndTraceIdAndSpanIdLength - 1] != '-')
            {
                return(false);
            }

            try
            {
                spanId = SpanId.FromBytes(Arrays.StringToByteArray(traceparent, VersionAndTraceIdLength, SpanIdLength));
            }
            catch (ArgumentOutOfRangeException)
            {
                // it's ok to still parse tracestate
                return(false);
            }

            if (traceparent.Length < VersionAndTraceIdAndSpanIdLength + OptionsLength)
            {
                return(false);
            }

            byte[] optionsArray;

            try
            {
                optionsArray = Arrays.StringToByteArray(traceparent, VersionAndTraceIdAndSpanIdLength, OptionsLength);
            }
            catch (ArgumentOutOfRangeException)
            {
                // it's ok to still parse tracestate
                return(false);
            }

            if ((optionsArray[0] | 1) == 1)
            {
                traceoptions = TraceOptions.Builder().SetIsSampled(true).Build();
            }

            if ((!bestAttempt) && (traceparent.Length != VersionAndTraceIdAndSpanIdLength + OptionsLength))
            {
                return(false);
            }

            if (bestAttempt)
            {
                if ((traceparent.Length > VersionAndTraceIdAndSpanIdLength + OptionsLength) &&
                    (traceparent[VersionAndTraceIdAndSpanIdLength + OptionsLength] != '-'))
                {
                    return(false);
                }
            }

            return(true);
        }
 public bool ShouldSample(ISpanContext parentContext, bool hasRemoteParent, ITraceId traceId, ISpanId spanId, string name, IEnumerable <ISpan> parentLinks)
 {
     return(false);
 }
Beispiel #4
0
 /// <summary>
 /// Creates a new <see cref="ISpanContext"/> with the given identifiers and options.
 /// </summary>
 /// <param name="traceId">The <see cref="ITraceId"/> to associate with the <see cref="ISpanContext"/>.</param>
 /// <param name="spanId">The <see cref="ISpanId"/> to associate with the <see cref="ISpanContext"/>.</param>
 /// <param name="traceOptions">The <see cref="TraceOptions"/> to associate with the <see cref="ISpanContext"/>.</param>
 /// <param name="tracestate">The <see cref="Tracestate"/> to associate with the <see cref="ISpanContext"/>.</param>
 /// <returns>A new <see cref="ISpanContext"/> with the given identifiers and options.</returns>
 public static ISpanContext Create(ITraceId traceId, ISpanId spanId, TraceOptions traceOptions, Tracestate tracestate)
 {
     return(new SpanContext(traceId, spanId, traceOptions, tracestate));
 }
 private string EncodeSpanId(ISpanId spanId)
 {
     return(spanId.ToLowerBase16());
 }
Beispiel #6
0
 public bool ShouldSample(SpanContext parentContext, ITraceId traceId, ISpanId spanId, string name, IEnumerable <ISpan> parentLinks)
 {
     return(true);
 }
 public bool ShouldSample(ISpanContext parentContext, bool hasRemoteParent, ITraceId traceId, ISpanId spanId, string name, IList <ISpan> parentLinks)
 {
     // If the parent is sampled keep the sampling decision.
     if (parentContext != null && parentContext.TraceOptions.IsSampled)
     {
         return(true);
     }
     if (parentLinks != null)
     {
         // If any parent link is sampled keep the sampling decision.
         foreach (ISpan parentLink in parentLinks)
         {
             if (parentLink.Context.TraceOptions.IsSampled)
             {
                 return(true);
             }
         }
     }
     // Always sample if we are within probability range. This is true even for child spans (that
     // may have had a different sampling decision made) to allow for different sampling policies,
     // and dynamic increases to sampling probabilities for debugging purposes.
     // Note use of '<' for comparison. This ensures that we never sample for probability == 0.0,
     // while allowing for a (very) small chance of *not* sampling if the id == Long.MAX_VALUE.
     // This is considered a reasonable tradeoff for the simplicity/performance requirements (this
     // code is executed in-line for every Span creation).
     return(Math.Abs(traceId.LowerLong) < IdUpperBound);
 }
 private SpanContext(ITraceId traceId, ISpanId spanId, TraceOptions traceOptions)
 {
     TraceId      = traceId;
     SpanId       = spanId;
     TraceOptions = traceOptions;
 }
 public bool ShouldSample(ISpanContext parentContext, bool hasRemoteParent, ITraceId traceId, ISpanId spanId, string name, IList <ISpan> parentLinks)
 {
     return(true);
 }