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); }
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); }
/// <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()); }
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); }