示例#1
0
        public void EqualsShouldReturnFalseIfSpanIdsAreNotEqual()
        {
            var spanState1 = new SpanState(TraceIdHigh, TraceId, null, 1, IsSampled, IsDebug);
            var spanState2 = new SpanState(TraceIdHigh, TraceId, null, 2, IsSampled, IsDebug);

            Assert.AreNotEqual(spanState1, spanState2);
        }
示例#2
0
        public void DefaultsValuesAreNotUsedIfValuesSpecified()
        {
            var spanState = new SpanState(1, 0, 2, SpanFlags.None);
            var started   = TimeUtils.UtcNow;

            // Make sure we choose something different thant the default values
            const string serviceName = SerializerUtils.DefaultServiceName + "_notDefault";
            var          hostPort    = SerializerUtils.DefaultEndPoint.Port + 1;

            const string name = "myRPCmethod";

            var span = new Span(spanState, started)
            {
                Endpoint = new IPEndPoint(IPAddress.Loopback, hostPort), ServiceName = serviceName, Name = name
            };

            AddClientSendReceiveAnnotations(span);

            var thriftSpan = ThriftSpanSerializer.ConvertToThrift(span);

            AssertSpanHasRequiredFields(thriftSpan);

            Assert.NotNull(thriftSpan);
            Assert.AreEqual(2, thriftSpan.Annotations.Count);

            thriftSpan.Annotations.ForEach(annotation =>
            {
                Assert.AreEqual(serviceName, annotation.Host.Service_name);
                Assert.AreEqual(SerializerUtils.IpToInt(IPAddress.Loopback), annotation.Host.Ipv4);
                Assert.AreEqual(hostPort, annotation.Host.Port);
            });

            Assert.AreEqual(name, thriftSpan.Name);
        }
示例#3
0
        public void RootSpanPropertyIsCorrect(long?parentSpanId)
        {
            var spanState = new SpanState(1, parentSpanId, 1, SpanFlags.None);
            var span      = new Span(spanState, TimeUtils.UtcNow);

            Assert.AreEqual(parentSpanId == null, span.IsRoot);
        }
示例#4
0
        public void TimestampConvertedForLocalComponent()
        {
            var startTime = DateTime.Now;
            var spanState = new SpanState(1, 0, 2, SpanFlags.None);
            var span      = new Span(spanState, TimeUtils.UtcNow);

            var recordStart  = new Record(spanState, startTime, Annotations.LocalOperationStart("Operation"));
            var visitorStart = new ZipkinAnnotationVisitor(recordStart, span);

            recordStart.Annotation.Accept(visitorStart);
            var recordStop  = new Record(spanState, startTime.AddHours(1), Annotations.LocalOperationStop());
            var visitorStop = new ZipkinAnnotationVisitor(recordStop, span);

            recordStop.Annotation.Accept(visitorStop);

            var thriftSpan = ThriftSpanSerializer.ConvertToThrift(span);

            Assert.AreEqual(startTime.ToUnixTimestamp(), thriftSpan.Timestamp);
            Assert.AreEqual(1, thriftSpan.Binary_annotations.Count);
            var endpoint = thriftSpan.Binary_annotations[0].Host;

            Assert.NotNull(endpoint);
            Assert.IsEmpty(endpoint.Service_name);
            Assert.IsNotNull(endpoint.Ipv4);
        }
        public void RootSpanPropertyIsCorrect(long?parentSpanId)
        {
            var spanState = new SpanState(1, parentSpanId, 1, isSampled: null, isDebug: false);
            var span      = new Span(spanState, TimeUtils.UtcNow);

            Assert.AreEqual(parentSpanId == null, span.IsRoot);
        }
示例#6
0
        public void HashCodeShouldVaryIfSpanIdsAreNotEqual()
        {
            var spanState1 = new SpanState(traceIdHigh, traceId, null, 1, flags);
            var spanState2 = new SpanState(traceIdHigh, traceId, null, 2, flags);

            Assert.AreNotEqual(spanState1.GetHashCode(), spanState2.GetHashCode());
        }
示例#7
0
        public void HashCodeShouldVaryIfSpanIdsAreNotEqual()
        {
            var spanState1 = new SpanState(TraceIdHigh, TraceId, null, 1, IsSampled, IsDebug);
            var spanState2 = new SpanState(TraceIdHigh, TraceId, null, 2, IsSampled, IsDebug);

            Assert.AreNotEqual(spanState1.GetHashCode(), spanState2.GetHashCode());
        }
示例#8
0
        public void DefaultsValuesAreUsedIfNothingSpecified()
        {
            var spanState = new SpanState(1, 0, 2, SpanFlags.None);
            var span      = new Span(spanState, TimeUtils.UtcNow);

            AddClientSendReceiveAnnotations(span);

            var thriftSpan = ThriftSpanSerializer.ConvertToThrift(span);

            AssertSpanHasRequiredFields(thriftSpan);

            const string defaultName        = SerializerUtils.DefaultRpcMethodName;
            const string defaultServiceName = SerializerUtils.DefaultServiceName;
            var          defaultIpv4        = SerializerUtils.IpToInt(SerializerUtils.DefaultEndPoint.Address);
            var          defaultPort        = SerializerUtils.DefaultEndPoint.Port;

            Assert.AreEqual(2, thriftSpan.Annotations.Count);
            thriftSpan.Annotations.ForEach(ann =>
            {
                Assert.AreEqual(defaultServiceName, ann.Host.Service_name);
                Assert.AreEqual(defaultIpv4, ann.Host.Ipv4);
                Assert.AreEqual(defaultPort, ann.Host.Port);
            });

            Assert.AreEqual(defaultName, thriftSpan.Name);
            Assert.IsNull(thriftSpan.Duration);
        }
示例#9
0
        public void EqualsShouldReturnFalseIfSpanIdsAreNotEqual()
        {
            var spanState1 = new SpanState(traceIdHigh, traceId, null, 1, flags);
            var spanState2 = new SpanState(traceIdHigh, traceId, null, 2, flags);

            Assert.AreNotEqual(spanState1, spanState2);
        }
示例#10
0
        public void AnnotationsAreCorrectlyRecorded()
        {
            var memoryTracer = new InMemoryTracer();

            var spanState = new SpanState(1, 0, 1, isSampled: null, isDebug: false);

            var rpcAnn    = Annotations.Rpc("GET RPC");
            var recordRpc = new Record(spanState, TimeUtils.UtcNow, rpcAnn);

            var servAnn        = Annotations.ServiceName("MyCriteoService");
            var recordServName = new Record(spanState, TimeUtils.UtcNow, servAnn);

            var servRecv    = Annotations.ServerRecv();
            var recordServR = new Record(spanState, TimeUtils.UtcNow, servRecv);

            var servSend    = Annotations.ServerSend();
            var recordServS = new Record(spanState, TimeUtils.UtcNow, servSend);

            memoryTracer.Record(recordRpc);
            memoryTracer.Record(recordServName);
            memoryTracer.Record(recordServR);
            memoryTracer.Record(recordServS);

            var records     = memoryTracer.Records.ToList();
            var annotations = records.Select(record => record.Annotation).ToList();

            Assert.AreEqual(4, annotations.Count());

            Assert.True(annotations.Contains(rpcAnn));
            Assert.True(annotations.Contains(servAnn));
            Assert.True(annotations.Contains(servRecv));
            Assert.True(annotations.Contains(servSend));
        }
示例#11
0
        public void SpansShouldBeFlushedAfterTtl()
        {
            var now = TimeUtils.UtcNow;

            var firstSpanState = new SpanState(traceId: 1, parentSpanId: 0, spanId: 4874542152, flags: SpanFlags.None);
            var record         = new Record(firstSpanState, now, Annotations.ServerRecv());

            _tracer.Record(record);

            // futureTime = now + (ttl - 4)
            var futureTime = now.AddSeconds(ZipkinTracer.TimeToLive.TotalSeconds - 4); // of course test will fail if TTL is set lower than 4 seconds

            _tracer.FlushOldSpans(futureTime);                                         // shouldn't do anything since we haven't reached span ttl yet

            _spanSender.Verify(sender => sender.Send(It.IsAny <byte[]>()), Times.Never());

            var newerSpanState = new SpanState(traceId: 2, parentSpanId: 0, spanId: 9988415021, flags: SpanFlags.None);
            var newerRecord    = new Record(newerSpanState, futureTime, Annotations.ServerRecv());

            _tracer.Record(newerRecord);           // creates a second span

            futureTime = futureTime.AddSeconds(5); // = now + (ttl - 4) + 5 = now + ttl + 1

            _tracer.FlushOldSpans(futureTime);     // should flush only the first span since we are 1 second past its TTL but 5 seconds before the second span TTL

            _spanSender.Verify(sender => sender.Send(It.IsAny <byte[]>()), Times.Once());

            // "ServerSend" should make the second span "complete" hence the second span should be sent immediately
            var newerComplementaryRecord = new Record(newerSpanState, futureTime, Annotations.ServerSend());

            _tracer.Record(newerComplementaryRecord);

            _spanSender.Verify(sender => sender.Send(It.IsAny <byte[]>()), Times.Exactly(2));
        }
示例#12
0
 public Span(SpanState spanState, DateTime spanCreated)
 {
     Annotations       = new List <ZipkinAnnotation>();
     BinaryAnnotations = new List <BinaryAnnotation>();
     Complete          = false;
     SpanState         = spanState;
     SpanCreated       = spanCreated;
 }
示例#13
0
        public void writeB3SingleFormat_sampled()
        {
            ITraceContext context =
                new SpanState(traceId: 1, parentSpanId: null, spanId: 3, isSampled: true, isDebug: false);
            var b3Format = B3SingleFormat.WriteB3SingleFormat(context);

            Assert.AreEqual(TraceId + '-' + SpanId + "-1", b3Format);
        }
示例#14
0
        public void parseB3SingleFormat_idsWithDebug()
        {
            const string input           = TraceId + "-" + SpanId + "-d";
            var          context         = B3SingleFormat.ParseB3SingleFormat(input);
            var          expectedContext = new SpanState(1, null, 3, null, true);

            Assert.AreEqual(expectedContext, context);
        }
示例#15
0
        public void parseB3SingleFormat_parent_unsampled()
        {
            const string input           = TraceId + "-" + SpanId + "-0-" + ParentId;
            var          context         = B3SingleFormat.ParseB3SingleFormat(input);
            var          expectedContext = new SpanState(1, 2, 3, false, false);

            Assert.AreEqual(expectedContext, context);
        }
示例#16
0
        public void parseB3SingleFormat_idsNotYetSampled()
        {
            const string input           = TraceId + "-" + SpanId;
            var          context         = B3SingleFormat.ParseB3SingleFormat(input);
            var          expectedContext = new SpanState(1, null, 3, null, false);

            Assert.AreEqual(expectedContext, context);
        }
示例#17
0
        public void writeB3SingleFormatWithoutParent_debug()
        {
            ITraceContext context =
                new SpanState(traceId: 1, parentSpanId: 2, spanId: 3, isSampled: false, isDebug: true);

            var b3Format = B3SingleFormat.WriteB3SingleFormatWithoutParentId(context);

            Assert.AreEqual(TraceId + '-' + SpanId + "-d", b3Format);
        }
示例#18
0
        public void writeB3SingleFormat_notYetSampled_128()
        {
            ITraceContext context = new SpanState(traceIdHigh: 9, traceId: 1, parentSpanId: null, spanId: 3,
                                                  isSampled: null, isDebug: false);

            var b3Format = B3SingleFormat.WriteB3SingleFormat(context);

            Assert.AreEqual("0000000000000009" + TraceId + "-" + SpanId, b3Format);
        }
示例#19
0
        private void RemoveThenLogSpan(SpanState spanState)
        {
            Span spanToLog;

            if (_spanMap.TryRemove(spanState, out spanToLog))
            {
                LogSpan(spanToLog);
            }
        }
示例#20
0
        public void TraceSamplingForced(bool?isSampled)
        {
            var spanState = new SpanState(1, 0, 1, isSampled: isSampled, isDebug: false);
            var trace     = Trace.CreateFromId(spanState);

            trace.ForceSampled();

            Assert.IsTrue(trace.CurrentSpan.Sampled);
        }
示例#21
0
        public void TraceSamplingForced(SpanFlags initialFlags)
        {
            var spanState = new SpanState(1, 0, 1, initialFlags);
            var trace     = Trace.CreateFromId(spanState);

            trace.ForceSampled();

            Assert.AreEqual(SamplingStatus.Sampled, trace.CurrentSpan.SamplingStatus);
        }
        private static string SerializeTraceId(SpanState spanState)
        {
            var hexTraceId = NumberUtils.EncodeLongToLowerHexString(spanState.TraceId);

            if (spanState.TraceIdHigh == SpanState.NoTraceIdHigh)
            {
                return(hexTraceId);
            }
            return(NumberUtils.EncodeLongToLowerHexString(spanState.TraceIdHigh) + hexTraceId);
        }
示例#23
0
        private static TimeSpan?GetSpanDuration(TimeSpan offset, params string[] annotations)
        {
            var spanState      = new SpanState(1, null, 2, isSampled: null, isDebug: false);
            var span           = new Span(spanState, TimeUtils.UtcNow);
            var annotationTime = span.SpanCreated;

            Array.ForEach(annotations, a =>
                          span.AddAnnotation(new ZipkinAnnotation(annotationTime, a)));

            span.SetAsComplete(annotationTime.Add(offset));

            return(span.Duration);
        }
示例#24
0
        public void FlagSampledShouldForward()
        {
            var dispatcher = new Mock <IRecordDispatcher>();

            TraceManager.Start(new VoidLogger(), dispatcher.Object);

            var spanState = new SpanState(1, 0, 1, isSampled: true, isDebug: false);
            var trace     = Trace.CreateFromId(spanState);

            trace.Record(Annotations.ClientRecv());

            dispatcher.Verify(d => d.Dispatch(It.IsAny <Record>()), Times.Once());
        }
示例#25
0
        public void FlagUnsetShouldForwardForBackwardCompatibility()
        {
            var dispatcher = new Mock <IRecordDispatcher>();

            TraceManager.Start(new VoidLogger(), dispatcher.Object);

            var spanState = new SpanState(1, 0, 1, SpanFlags.None);
            var trace     = Trace.CreateFromId(spanState);

            trace.Record(Annotations.ClientRecv());

            dispatcher.Verify(d => d.Dispatch(It.IsAny <Record>()), Times.Once());
        }
示例#26
0
        public void FlagNotSampledShouldNotForward()
        {
            var dispatcher = new Mock <IRecordDispatcher>();

            TraceManager.Start(new VoidLogger(), dispatcher.Object);

            var spanState = new SpanState(1, 0, 1, SpanFlags.SamplingKnown);
            var trace     = Trace.CreateFromId(spanState);

            trace.Record(Annotations.ClientRecv());

            dispatcher.Verify(d => d.Dispatch(It.IsAny <Record>()), Times.Never);
        }
        public void ExtraFieldShouldBeInjectedInCarrier()
        {
            var extra = new ExtraFieldPropagation.Extra();

            extra.Put(Key1, Key1Value);
            var context = new SpanState(_context, new List <object> {
                extra
            });

            Injector.Inject(context, _carrier);

            Assert.True(_carrier.Contains(new KeyValuePair <string, string>(Key1, Key1Value)));
        }
示例#28
0
        public void MinimumDurationShouldBeAMicrosecond()
        {
            var spanState      = new SpanState(1, null, 2, isSampled: null, isDebug: false);
            var span           = new Span(spanState, TimeUtils.UtcNow);
            var annotationTime = span.SpanCreated;

            span.AddBinaryAnnotation(new BinaryAnnotation(zipkinCoreConstants.LOCAL_COMPONENT,
                                                          Encoding.UTF8.GetBytes("lc1"), AnnotationType.STRING, annotationTime,
                                                          SerializerUtils.DefaultServiceName, SerializerUtils.DefaultEndPoint));
            span.SetAsComplete(annotationTime.AddTicks(1));

            Assert.NotNull(span.Duration);
            Assert.AreEqual(0.001, span.Duration.Value.TotalMilliseconds);
        }
示例#29
0
        public void WhiteSpacesAreRemovedFromServiceName()
        {
            var spanState = new SpanState(1, 0, 2, SpanFlags.None);
            var span      = new Span(spanState, TimeUtils.UtcNow)
            {
                ServiceName = "my Criteo Service"
            };

            AddClientSendReceiveAnnotations(span);

            var thriftSpan = ThriftSpanSerializer.ConvertToThrift(span);

            Assert.AreEqual("my_Criteo_Service", thriftSpan.Annotations[0].Host.Service_name);
        }
        public void HeadersAreCorrectlySet(string expectedTraceId, long?parentSpanId, string expectedParentSpanId, string expectedSpanId, bool setSampled, string expectedFlags, string expectedSampled, int expectedCount)
        {
            var spanState = new SpanState(1, parentSpanId, 250, setSampled ? (SpanFlags.SamplingKnown | SpanFlags.Sampled) : SpanFlags.None);
            var trace     = Trace.CreateFromId(spanState);

            var headersNvc = new NameValueCollection();

            _injector.Inject(trace, headersNvc);
            CheckHeaders(headersNvc, expectedTraceId, expectedParentSpanId, expectedSpanId, expectedFlags, expectedSampled, expectedCount);

            var headersDict = new Dictionary <string, string>();

            _injector.Inject(trace, headersDict);
            CheckHeaders(headersDict, expectedTraceId, expectedParentSpanId, expectedSpanId, expectedFlags, expectedSampled, expectedCount);
        }