private SpanContext(ITraceId traceId, ISpanId spanId, TraceOptions traceOptions, Tracestate tracestate) { this.TraceId = traceId; this.SpanId = spanId; this.TraceOptions = traceOptions; this.Tracestate = tracestate; }
private static bool MakeSamplingDecision( SpanContext parent, string name, ISampler sampler, IEnumerable <ISpan> parentLinks, ITraceId traceId, ISpanId spanId, ITraceParams activeTraceParams) { // If users set a specific sampler in the SpanBuilder, use it. if (sampler != null) { return(sampler.ShouldSample(parent, traceId, spanId, name, parentLinks)); } // Use the default sampler if this is a root Span or this is an entry point Span (has remote // parent). if (parent == null || !parent.IsValid) { return(activeTraceParams .Sampler .ShouldSample(parent, traceId, spanId, name, parentLinks)); } // Parent is always different than null because otherwise we use the default sampler. return(parent.TraceOptions.IsSampled || IsAnyParentLinkSampled(parentLinks)); }
private Link(ITraceId traceId, ISpanId spanId, LinkType type, IDictionary <string, IAttributeValue> attributes) { this.TraceId = traceId ?? throw new ArgumentNullException(nameof(traceId)); this.SpanId = spanId ?? throw new ArgumentNullException(nameof(spanId)); this.Type = type; this.Attributes = attributes ?? throw new ArgumentNullException(nameof(attributes)); }
public bool ShouldSample(SpanContext parentContext, ITraceId traceId, ISpanId spanId, string name, IEnumerable <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) < this.IdUpperBound); }
public SamplersTest() { traceId = TraceId.GenerateRandomId(random); parentSpanId = SpanId.GenerateRandomId(random); spanId = SpanId.GenerateRandomId(random); sampledSpanContext = SpanContext.Create(traceId, parentSpanId, TraceOptions.Builder().SetIsSampled(true).Build(), Tracestate.Empty); notSampledSpanContext = SpanContext.Create(traceId, parentSpanId, TraceOptions.Default, Tracestate.Empty); sampledSpan = new TestSpan(sampledSpanContext, SpanOptions.RecordEvents); }
public SamplersTest() { traceId = TraceId.GenerateRandomId(random); parentSpanId = SpanId.GenerateRandomId(random); spanId = SpanId.GenerateRandomId(random); sampledSpanContext = SpanContext.Create(traceId, parentSpanId, TraceOptions.Builder().SetIsSampled(true).Build()); notSampledSpanContext = SpanContext.Create(traceId, parentSpanId, TraceOptions.DEFAULT); sampledSpan = new NoopSpan(sampledSpanContext, SpanOptions.RECORD_EVENTS); }
public async Task HttpDepenenciesCollectorInjectsHeadersAsync() { var startEndHandler = new Mock <IStartEndHandler>(); var serverLifeTime = TestServer.RunServer( (ctx) => { ctx.Response.StatusCode = 200; ctx.Response.OutputStream.Close(); }, out string host, out int port); var url = $"http://{host}:{port}/"; ITraceId expectedTraceId = TraceId.Invalid; ISpanId expectedSpanId = SpanId.Invalid; using (serverLifeTime) { var tracer = new Tracer(new RandomGenerator(), startEndHandler.Object, new DateTimeOffsetClock(), new TraceConfig()); var tf = new Mock <ITextFormat>(); tf .Setup(m => m.Inject <HttpRequestMessage>(It.IsAny <ISpanContext>(), It.IsAny <HttpRequestMessage>(), It.IsAny <Action <HttpRequestMessage, string, string> >())) .Callback((ISpanContext sc, HttpRequestMessage obj, Action <HttpRequestMessage, string, string> setter) => { expectedTraceId = sc.TraceId; expectedSpanId = sc.SpanId; }); var propagationComponent = new Mock <IPropagationComponent>(); propagationComponent.SetupGet(m => m.TextFormat).Returns(tf.Object); using (var dc = new DependenciesCollector(new DependenciesCollectorOptions(), tracer, Samplers.AlwaysSample, propagationComponent.Object)) { using (var c = new HttpClient()) { var request = new HttpRequestMessage { RequestUri = new Uri(url), Method = new HttpMethod("GET"), }; await c.SendAsync(request); } } } Assert.Equal(2, startEndHandler.Invocations.Count); // begin and end was called var spanData = ((Span)startEndHandler.Invocations[1].Arguments[0]).ToSpanData(); Assert.Equal(expectedTraceId, spanData.Context.TraceId); Assert.Equal(expectedSpanId, spanData.Context.SpanId); }
private string EncodeTraceId(ITraceId traceId) { var id = traceId.ToLowerBase16(); if (id.Length > 16 && this.options.UseShortTraceIds) { id = id.Substring(id.Length - 16, 16); } return(id); }
public int CompareTo(ITraceId other) { TraceId that = other as TraceId; for (int i = 0; i < SIZE; i++) { if (bytes[i] != that.bytes[i]) { sbyte b1 = (sbyte)bytes[i]; sbyte b2 = (sbyte)that.bytes[i]; return(b1 < b2 ? -1 : 1); } } return(0); }
public override ISpanContext FromByteArray(byte[] bytes) { if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } if (bytes.Length == 0 || bytes[0] != VERSION_ID) { throw new SpanContextParseException("Unsupported version."); } ITraceId traceId = TraceId.INVALID; ISpanId spanId = SpanId.INVALID; TraceOptions traceOptions = TraceOptions.DEFAULT; int pos = 1; try { if (bytes.Length > pos && bytes[pos] == TRACE_ID_FIELD_ID) { traceId = TraceId.FromBytes(bytes, pos + ID_SIZE); pos += ID_SIZE + TraceId.SIZE; } if (bytes.Length > pos && bytes[pos] == SPAN_ID_FIELD_ID) { spanId = SpanId.FromBytes(bytes, pos + ID_SIZE); pos += ID_SIZE + SpanId.SIZE; } if (bytes.Length > pos && bytes[pos] == TRACE_OPTION_FIELD_ID) { traceOptions = TraceOptions.FromBytes(bytes, pos + ID_SIZE); } return(SpanContext.Create(traceId, spanId, traceOptions)); } catch (Exception e) { throw new SpanContextParseException("Invalid input.", e); } }
public override ISpanContext FromByteArray(byte[] bytes) { if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } if (bytes.Length == 0 || bytes[0] != VersionId) { throw new SpanContextParseException("Unsupported version."); } ITraceId traceId = TraceId.Invalid; ISpanId spanId = SpanId.Invalid; TraceOptions traceOptions = TraceOptions.Default; int pos = 1; try { if (bytes.Length > pos && bytes[pos] == TraceIdFieldId) { traceId = TraceId.FromBytes(bytes, pos + IdSize); pos += IdSize + TraceId.Size; } if (bytes.Length > pos && bytes[pos] == SpanIdFieldId) { spanId = SpanId.FromBytes(bytes, pos + IdSize); pos += IdSize + SpanId.Size; } if (bytes.Length > pos && bytes[pos] == TraceOptionsFieldId) { traceOptions = TraceOptions.FromBytes(bytes, pos + IdSize); } return(SpanContext.Create(traceId, spanId, traceOptions, Tracestate.Empty)); } catch (Exception e) { throw new SpanContextParseException("Invalid input.", e); } }
private Link(ITraceId traceId, ISpanId spanId, LinkType type, IDictionary <string, IAttributeValue> attributes) { if (traceId == null) { throw new ArgumentNullException(nameof(traceId)); } if (spanId == null) { throw new ArgumentNullException(nameof(spanId)); } if (attributes == null) { throw new ArgumentNullException(nameof(attributes)); } TraceId = traceId; SpanId = spanId; Type = type; Attributes = attributes; }
public void StartRemoteChildSpan_WithProbabilitySamplerDefaultSampler() { var configMock = Mock.Get <ITraceConfig>(traceConfig); configMock.Setup((c) => c.ActiveTraceParams).Returns(TraceParams.DEFAULT); // This traceId will not be sampled by the ProbabilitySampler because the first 8 bytes as long // is not less than probability * Long.MAX_VALUE; ITraceId traceId = TraceId.FromBytes( new byte[] { (byte)0x8F, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }); // If parent is sampled then the remote child must be sampled. ISpan childSpan = SpanBuilder.CreateWithRemoteParent( SPAN_NAME, SpanContext.Create( traceId, SpanId.GenerateRandomId(randomHandler), TraceOptions.Builder().SetIsSampled(true).Build()), spanBuilderOptions) .StartSpan(); Assert.True(childSpan.Context.IsValid); Assert.Equal(traceId, childSpan.Context.TraceId); Assert.True(childSpan.Context.TraceOptions.IsSampled); childSpan.End(); Assert.Equal(TraceParams.DEFAULT, traceConfig.ActiveTraceParams); // If parent is not sampled then the remote child must be not sampled. childSpan = SpanBuilder.CreateWithRemoteParent( SPAN_NAME, SpanContext.Create( traceId, SpanId.GenerateRandomId(randomHandler), TraceOptions.DEFAULT), spanBuilderOptions) .StartSpan(); Assert.True(childSpan.Context.IsValid); Assert.Equal(traceId, childSpan.Context.TraceId); Assert.False(childSpan.Context.TraceOptions.IsSampled); childSpan.End(); }
private SpanContext(ITraceId traceId, ISpanId spanId, TraceOptions traceOptions) { TraceId = traceId; SpanId = spanId; TraceOptions = traceOptions; }
public static ISpanContext Create(ITraceId traceId, ISpanId spanId, TraceOptions traceOptions) { return(new SpanContext(traceId, spanId, traceOptions)); }
public bool ShouldSample(ISpanContext parentContext, bool hasRemoteParent, ITraceId traceId, ISpanId spanId, string name, IList <ISpan> parentLinks) { return(false); }
public bool ShouldSample(ISpanContext parentContext, bool hasRemoteParent, ITraceId traceId, ISpanId spanId, string name, IEnumerable <ISpan> parentLinks) { throw new System.NotImplementedException(); }
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 void ProbabilitySampler_SampleBasedOnTraceId() { ISampler defaultProbability = ProbabilitySampler.Create(0.0001); // This traceId will not be sampled by the ProbabilitySampler because the first 8 bytes as long // is not less than probability * Long.MAX_VALUE; ITraceId notSampledtraceId = TraceId.FromBytes( new byte[] { 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, }); Assert.False( defaultProbability.ShouldSample( null, notSampledtraceId, SpanId.GenerateRandomId(random), SPAN_NAME, new List <ISpan>())); // This traceId will be sampled by the ProbabilitySampler because the first 8 bytes as long // is less than probability * Long.MAX_VALUE; ITraceId sampledtraceId = TraceId.FromBytes( new byte[] { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, }); Assert.True( defaultProbability.ShouldSample( null, sampledtraceId, SpanId.GenerateRandomId(random), SPAN_NAME, new List <ISpan>())); }
public bool ShouldSample(SpanContext parentContext, ITraceId traceId, ISpanId spanId, string name, IEnumerable <ISpan> parentLinks) { return(false); }
public bool ShouldSample(ISpanContext parentContext, bool hasRemoteParent, ITraceId traceId, ISpanId spanId, string name, IEnumerable <ISpan> parentLinks) { return(true); }