/// <inheritdoc /> public override Decision ShouldSample(SpanContext parentContext, ActivityTraceId traceId, ActivitySpanId spanId, string name, IDictionary <string, object> attributes, IEnumerable <Link> links) { // If the parent is sampled keep the sampling decision. if (parentContext != null && parentContext.IsValid && (parentContext.TraceOptions & ActivityTraceFlags.Recorded) != 0) { return(new Decision(true)); } if (links != null) { // If any parent link is sampled keep the sampling decision. foreach (var parentLink in links) { if ((parentLink.Context.TraceOptions & ActivityTraceFlags.Recorded) != 0) { return(new Decision(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). Span <byte> traceIdBytes = stackalloc byte[16]; traceId.CopyTo(traceIdBytes); return(Math.Abs(this.GetLowerLong(traceIdBytes)) < this.idUpperBound ? new Decision(true) : new Decision(false)); }
public Int128(ActivityTraceId traceId) { var bytes = new byte[TraceIdBytes]; traceId.CopyTo(bytes); this.High = BitConverter.ToInt64(bytes, 0); this.Low = BitConverter.ToInt64(bytes, 8); }
public Int128(ActivityTraceId traceId) { Span <byte> bytes = stackalloc byte[TraceIdBytes]; traceId.CopyTo(bytes); if (BitConverter.IsLittleEndian) { bytes.Reverse(); } var longs = MemoryMarshal.Cast <byte, long>(bytes); this.High = BitConverter.IsLittleEndian ? longs[1] : longs[0]; this.Low = BitConverter.IsLittleEndian ? longs[0] : longs[1]; }
public Int128(ActivityTraceId traceId) { var bytes = new byte[TraceIdBytes]; traceId.CopyTo(bytes); if (BitConverter.IsLittleEndian) { Array.Reverse(bytes); this.High = BitConverter.ToInt64(bytes, 8); this.Low = BitConverter.ToInt64(bytes, 0); } else { this.High = BitConverter.ToInt64(bytes, 0); this.Low = BitConverter.ToInt64(bytes, 8); } }
public void ActivityTraceIdTests() { Span <byte> idBytes1 = stackalloc byte[16]; Span <byte> idBytes2 = stackalloc byte[16]; // Empty Constructor string zeros = "00000000000000000000000000000000"; ActivityTraceId emptyId = new ActivityTraceId(); Assert.Equal(zeros, emptyId.ToHexString()); emptyId.CopyTo(idBytes1); Assert.Equal(new byte[16], idBytes1.ToArray()); Assert.True(emptyId == new ActivityTraceId()); Assert.True(!(emptyId != new ActivityTraceId())); Assert.True(emptyId.Equals(new ActivityTraceId())); Assert.True(emptyId.Equals((object)new ActivityTraceId())); Assert.Equal(new ActivityTraceId().GetHashCode(), emptyId.GetHashCode()); // NewActivityTraceId ActivityTraceId newId1 = ActivityTraceId.CreateRandom(); Assert.True(IsLowerCaseHex(newId1.ToHexString())); Assert.Equal(32, newId1.ToHexString().Length); ActivityTraceId newId2 = ActivityTraceId.CreateRandom(); Assert.Equal(32, newId1.ToHexString().Length); Assert.NotEqual(newId1.ToHexString(), newId2.ToHexString()); // Test equality Assert.True(newId1 != newId2); Assert.True(!(newId1 == newId2)); Assert.True(!(newId1.Equals(newId2))); Assert.True(!(newId1.Equals((object)newId2))); Assert.NotEqual(newId1.GetHashCode(), newId2.GetHashCode()); ActivityTraceId newId3 = ActivityTraceId.CreateFromString("00000000000000000000000000000001".AsSpan()); Assert.True(newId3 != emptyId); Assert.True(!(newId3 == emptyId)); Assert.True(!(newId3.Equals(emptyId))); Assert.True(!(newId3.Equals((object)emptyId))); Assert.NotEqual(newId3.GetHashCode(), emptyId.GetHashCode()); // Use in Dictionary (this does assume we have no collisions in IDs over 100 tries (very good). var dict = new Dictionary <ActivityTraceId, string>(); for (int i = 0; i < 100; i++) { var newId7 = ActivityTraceId.CreateRandom(); dict[newId7] = newId7.ToHexString(); } int ctr = 0; foreach (string value in dict.Values) { string valueInDict; Assert.True(dict.TryGetValue(ActivityTraceId.CreateFromString(value.AsSpan()), out valueInDict)); Assert.Equal(value, valueInDict); ctr++; } Assert.Equal(100, ctr); // We got out what we put in. // AsBytes and Byte constructor. newId2.CopyTo(idBytes2); ActivityTraceId newId2Clone = ActivityTraceId.CreateFromBytes(idBytes2); Assert.Equal(newId2.ToHexString(), newId2Clone.ToHexString()); newId2Clone.CopyTo(idBytes1); Assert.Equal(idBytes2.ToArray(), idBytes1.ToArray()); Assert.True(newId2 == newId2Clone); Assert.True(newId2.Equals(newId2Clone)); Assert.True(newId2.Equals((object)newId2Clone)); Assert.Equal(newId2.GetHashCode(), newId2Clone.GetHashCode()); // String constructor and ToHexString(). string idStr = "0123456789abcdef0123456789abcdef"; ActivityTraceId id = ActivityTraceId.CreateFromString(idStr.AsSpan()); Assert.Equal(idStr, id.ToHexString()); // Utf8 Constructor. byte[] idUtf8 = Encoding.UTF8.GetBytes(idStr); ActivityTraceId id1 = ActivityTraceId.CreateFromUtf8String(idUtf8); Assert.Equal(idStr, id1.ToHexString()); // ToString Assert.Equal(idStr, id.ToString()); }