public async Task FlushBothBuffers()
        {
            // When the back buffer is full, both buffers should be flushed
            var api = new Mock <IApi>();

            var sizeOfTrace = ComputeSizeOfTrace(CreateTrace(1));

            // Make the buffer size big enough for a single trace
            var agent = new AgentWriter(api.Object, statsd: null, automaticFlush: false, maxBufferSize: (sizeOfTrace * 2) + SpanBuffer.HeaderSize - 1);

            agent.WriteTrace(CreateTrace(1));
            agent.WriteTrace(CreateTrace(1));

            Assert.True(agent.ActiveBuffer == agent.BackBuffer);
            Assert.True(agent.FrontBuffer.IsFull);
            Assert.Equal(1, agent.FrontBuffer.TraceCount);
            Assert.False(agent.BackBuffer.IsFull);
            Assert.Equal(1, agent.BackBuffer.TraceCount);

            await agent.FlushTracesAsync();

            Assert.True(agent.FrontBuffer.IsEmpty);
            Assert.True(agent.BackBuffer.IsEmpty);

            api.Verify(a => a.SendTracesAsync(It.IsAny <ArraySegment <byte> >(), 1), Times.Exactly(2));
        }
        public async Task FlushTwice()
        {
            var w = new AgentWriter(_api.Object, statsd: null);
            await w.FlushAndCloseAsync();

            await w.FlushAndCloseAsync();
        }
        public Task FaultyApi()
        {
            // The flush thread should be able to recover from an error when calling the API
            // Also, it should free the faulty buffer
            var api   = new Mock <IApi>();
            var agent = new AgentWriter(api.Object, statsd: null);

            var mutex = new ManualResetEventSlim();

            agent.Flushed += () => mutex.Set();

            api.Setup(a => a.SendTracesAsync(It.IsAny <ArraySegment <byte> >(), It.IsAny <int>()))
            .Returns(() =>
            {
                throw new InvalidOperationException();
            });

            agent.WriteTrace(CreateTrace(1));

            mutex.Wait();

            Assert.True(agent.ActiveBuffer == agent.FrontBuffer);
            Assert.True(agent.FrontBuffer.IsEmpty);
            Assert.True(agent.BackBuffer.IsEmpty);

            return(agent.FlushAndCloseAsync());
        }
Esempio n. 4
0
        public async Task WriteTrace_2Traces_SendToApi(bool synchronousSend)
        {
            var tracer = new Mock <ISignalFxTracer>();

            tracer.Setup(x => x.DefaultServiceName).Returns("Default");

            var api         = new Mock <IApi>();
            var agentWriter = new AgentWriter(api.Object, statsd: null, synchronousSend);

            var parentSpanContext = new Mock <ISpanContext>();
            var traceContext      = new Mock <ITraceContext>();
            var spanContext       = new SpanContext(parentSpanContext.Object, traceContext.Object, serviceName: null);

            // TODO:bertrand it is too complicated to setup such a simple test
            var trace = new[] { new Span(spanContext, start: null) };

            agentWriter.WriteTrace(trace);
            if (!synchronousSend)
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
            }

            api.Verify(x => x.SendTracesAsync(It.Is <Span[][]>(y => y.Single().Equals(trace))), Times.Once);

            trace = new[] { new Span(spanContext, start: null) };
            agentWriter.WriteTrace(trace);
            if (!synchronousSend)
            {
                await Task.Delay(TimeSpan.FromSeconds(3));
            }

            api.Verify(x => x.SendTracesAsync(It.Is <Span[][]>(y => y.Single().Equals(trace))), Times.Once);
        }
        public async Task FlushTwice()
        {
            var w = new AgentWriter(_api.Object, new NullMetrics());
            await w.FlushAndCloseAsync();

            await w.FlushAndCloseAsync();
        }
Esempio n. 6
0
        internal static Tracer Create(Uri agentEndpoint, string serviceName, DelegatingHandler delegatingHandler = null, bool isDebugEnabled = false)
        {
            var api         = new Api(agentEndpoint, delegatingHandler);
            var agentWriter = new AgentWriter(api);
            var tracer      = new Tracer(agentWriter, serviceName, isDebugEnabled);

            return(tracer);
        }
Esempio n. 7
0
        public async Task FlushTwice(bool synchronousSend)
        {
            var api = new Mock <IApi>();
            var w   = new AgentWriter(api.Object, statsd: null, synchronousSend);
            await w.FlushAndCloseAsync();

            await w.FlushAndCloseAsync();
        }
        public CIAgentWriter(ImmutableTracerSettings settings, ISampler sampler, int maxBufferSize = DefaultMaxBufferSize)
        {
            var isPartialFlushEnabled = settings.ExporterSettings.PartialFlushEnabled;
            var apiRequestFactory     = TracesTransportStrategy.Get(settings.ExporterSettings);
            var api = new Api(apiRequestFactory, null, rates => sampler.SetDefaultSampleRates(rates), isPartialFlushEnabled);

            _agentWriter = new AgentWriter(api, null, maxBufferSize: maxBufferSize);
        }
        private static bool WaitForDequeue(AgentWriter agent, bool wakeUpThread = true, int delay = -1)
        {
            var mutex = new ManualResetEventSlim();

            agent.WriteWatermark(() => mutex.Set(), wakeUpThread);

            return(mutex.Wait(delay));
        }
        public AgentWriterTests()
        {
            var tracer = new Mock <IDatadogTracer>();

            tracer.Setup(x => x.DefaultServiceName).Returns("Default");

            _api         = new Mock <IApi>();
            _agentWriter = new AgentWriter(_api.Object, statsd: null);
        }
Esempio n. 11
0
        public AgentWriterTests()
        {
            _tracer = new Mock <IDatadogTracer>();
            _tracer.Setup(x => x.DefaultServiceName).Returns("Default");
            var context = new Mock <ITraceContext>();

            _api         = new Mock <IApi>();
            _agentWriter = new AgentWriter(_api.Object);
        }
Esempio n. 12
0
        internal static OpenTracingTracer CreateTracer(Uri agentEndpoint, string defaultServiceName = null, DelegatingHandler delegatingHandler = null, bool isDebugEnabled = false)
        {
            var api         = new Api(agentEndpoint, delegatingHandler);
            var agentWriter = new AgentWriter(api);
            var ddTracer    = new Tracer(agentWriter, defaultServiceName, isDebugEnabled);
            var tracer      = new OpenTracingTracer(ddTracer);

            return(tracer);
        }
Esempio n. 13
0
        public OriginTagSendTraces()
        {
            var settings = new TracerSettings();

            _testApi = new TestApi();
            var agentWriter = new AgentWriter(_testApi, statsd: null);

            _tracer = new Tracer(settings, agentWriter, sampler: null, scopeManager: null, statsd: null);
        }
Esempio n. 14
0
        public SendTracesToZipkinCollector()
        {
            var settings = new TracerSettings();

            _httpRecorder = new RecordHttpHandler();
            var api         = new ZipkinApi(settings, _httpRecorder, statsd: null);
            var agentWriter = new AgentWriter(api, statsd: null);

            _tracer = new Tracer(settings, agentWriter, sampler: null, scopeManager: null, statsd: null);
        }
        public Task SwitchBuffer()
        {
            // Make sure that the agent is able to switch to the secondary buffer when the primary is full/busy
            var api   = new Mock <IApi>();
            var agent = new AgentWriter(api.Object, statsd: null);

            var barrier = new Barrier(2);

            api.Setup(a => a.SendTracesAsync(It.IsAny <ArraySegment <byte> >(), It.IsAny <int>()))
            .Callback(() =>
            {
                barrier.SignalAndWait();
                barrier.SignalAndWait();
            })
            .Returns(Task.FromResult(true));

            agent.WriteTrace(CreateTrace(1));

            // Wait for the flush operation
            barrier.SignalAndWait();

            // At this point, the flush thread is stuck in Api.SendTracesAsync, and the frontBuffer should be active and locked
            Assert.True(agent.ActiveBuffer == agent.FrontBuffer);
            Assert.True(agent.FrontBuffer.IsLocked);
            Assert.Equal(1, agent.FrontBuffer.TraceCount);
            Assert.Equal(1, agent.FrontBuffer.SpanCount);

            var mutex = new ManualResetEventSlim();

            agent.WriteTrace(CreateTrace(2));

            // Wait for the trace to be dequeued
            WaitForDequeue(agent);

            // Since the frontBuffer was locked, the buffers should have been swapped
            Assert.True(agent.ActiveBuffer == agent.BackBuffer);
            Assert.Equal(1, agent.BackBuffer.TraceCount);
            Assert.Equal(2, agent.BackBuffer.SpanCount);

            // Unblock the flush thread
            barrier.SignalAndWait();

            // Wait for the next flush operation
            barrier.SignalAndWait();

            // Back buffer should still be active and being flushed
            Assert.True(agent.ActiveBuffer == agent.BackBuffer);
            Assert.True(agent.BackBuffer.IsLocked);
            Assert.False(agent.FrontBuffer.IsLocked);

            // Unblock and exit
            barrier.Dispose();
            return(agent.FlushAndCloseAsync());
        }
        public async Task AddsTraceKeepRateMetricToRootSpan()
        {
            // Traces should be dropped when both buffers are full
            var calculator = new MovingAverageKeepRateCalculator(windowSize: 10, Timeout.InfiniteTimeSpan);

            var tracer = new Mock <IDatadogTracer>();

            tracer.Setup(x => x.DefaultServiceName).Returns("Default");
            var traceContext    = new TraceContext(tracer.Object);
            var rootSpanContext = new SpanContext(null, traceContext, null);
            var rootSpan        = new Span(rootSpanContext, DateTimeOffset.UtcNow);
            var childSpan       = new Span(new SpanContext(rootSpanContext, traceContext, null), DateTimeOffset.UtcNow);

            traceContext.AddSpan(rootSpan);
            traceContext.AddSpan(childSpan);
            var trace       = new[] { rootSpan, childSpan };
            var sizeOfTrace = ComputeSizeOfTrace(trace);

            // Make the buffer size big enough for a single trace
            var api = new Mock <IApi>();

            api.Setup(x => x.SendTracesAsync(It.IsAny <ArraySegment <byte> >(), It.IsAny <int>()))
            .ReturnsAsync(() => true);
            var agent = new AgentWriter(api.Object, statsd: null, calculator, automaticFlush: false, maxBufferSize: (sizeOfTrace * 2) + SpanBuffer.HeaderSize - 1, batchInterval: 100);

            // Fill both buffers
            agent.WriteTrace(trace);
            agent.WriteTrace(trace);

            // Drop one
            agent.WriteTrace(trace);
            await agent.FlushTracesAsync(); // Force a flush to make sure the trace is written to the API

            // Write another one
            agent.WriteTrace(trace);
            await agent.FlushTracesAsync(); // Force a flush to make sure the trace is written to the API

            api.Verify();
            api.Invocations.Clear();

            // Write trace and update keep rate
            calculator.UpdateBucket();
            agent.WriteTrace(trace);
            await agent.FlushTracesAsync(); // Force a flush to make sure the trace is written to the API

            const double expectedTraceKeepRate = 0.75;

            rootSpan.SetMetric(Metrics.TracesKeepRate, expectedTraceKeepRate);
            var expectedData = Vendors.MessagePack.MessagePackSerializer.Serialize(trace, new FormatterResolverWrapper(SpanFormatterResolver.Instance));
            await agent.FlushAndCloseAsync();

            api.Verify(x => x.SendTracesAsync(It.Is <ArraySegment <byte> >(y => Equals(y, expectedData)), It.Is <int>(i => i == 1)), Times.Once);
        }
Esempio n. 17
0
        public SendTracesToAgent()
        {
            var settings = new TracerSettings();

            var endpoint = new Uri("http://localhost:8126");

            _httpRecorder = new RecordHttpHandler();
            var api         = new Api(endpoint, apiRequestFactory: null, statsd: null);
            var agentWriter = new AgentWriter(api, new NullMetrics());

            _tracer = new Tracer(settings, plugins: null, agentWriter, sampler: null, scopeManager: null, statsd: null);
        }
        public SendTracesToAgent()
        {
            var settings = new TracerSettings();

            var endpoint = new Uri("http://localhost:8126");

            _httpRecorder = new RecordHttpHandler();
            var api         = new Api(endpoint, _httpRecorder);
            var agentWriter = new AgentWriter(api);

            _tracer = new Tracer(settings, agentWriter, sampler: null, scopeManager: null);
        }
Esempio n. 19
0
        public SendTracesToZipkinCollector()
        {
            var settings = new TracerSettings()
            {
                AgentUri = new System.Uri("http://localhost:9411/api/v2/spans")
            };

            var api         = new ZipkinApi(settings);
            var agentWriter = new AgentWriter(api, statsd: null);

            _tracer = new Tracer(settings, agentWriter, sampler: null, scopeManager: null, statsd: null);
        }
Esempio n. 20
0
        public OpenTracingSendTracesToAgent()
        {
            var settings = new TracerSettings();

            _httpRecorder = new RecordHttpHandler();
            var api         = new ZipkinApi(settings, _httpRecorder);
            var agentWriter = new AgentWriter(api, statsd: null, synchronousSend: false);

            var tracer = new Tracer(settings, agentWriter, sampler: null, scopeManager: null, statsd: null);

            _tracer = new OpenTracingTracer(tracer);
        }
        public AgentWriterTests()
        {
            var tracer = new Mock<IDatadogTracer>();
            tracer.Setup(x => x.DefaultServiceName).Returns("Default");

            _api = new Mock<IApi>();
            _agentWriter = new AgentWriter(_api.Object, statsd: null);

            var parentSpanContext = new Mock<ISpanContext>();
            var traceContext = new Mock<ITraceContext>();
            _spanContext = new SpanContext(parentSpanContext.Object, traceContext.Object, serviceName: null);
        }
        public void DropTraces()
        {
            // Traces should be dropped when both buffers are full
            var statsd = new Mock <IDogStatsd>();

            var sizeOfTrace = ComputeSizeOfTrace(CreateTrace(1));

            // Make the buffer size big enough for a single trace
            var agent = new AgentWriter(Mock.Of <IApi>(), statsd.Object, automaticFlush: false, (sizeOfTrace * 2) + SpanBuffer.HeaderSize - 1);

            // Fill the two buffers
            agent.WriteTrace(CreateTrace(1));
            agent.WriteTrace(CreateTrace(1));

            // Buffers should have swapped
            Assert.True(agent.ActiveBuffer == agent.BackBuffer);

            // The agent does not know yet that the new active buffer is full
            Assert.False(agent.ActiveBuffer.IsFull);

            // Both buffers have 1 trace stored
            Assert.Equal(1, agent.FrontBuffer.TraceCount);
            Assert.Equal(1, agent.FrontBuffer.SpanCount);
            Assert.Equal(1, agent.BackBuffer.TraceCount);
            Assert.Equal(1, agent.BackBuffer.SpanCount);

            statsd.Verify(s => s.Increment(TracerMetricNames.Queue.EnqueuedTraces, 1, 1, null), Times.Exactly(2));
            statsd.Verify(s => s.Increment(TracerMetricNames.Queue.EnqueuedSpans, 1, 1, null), Times.Exactly(2));
            statsd.VerifyNoOtherCalls();
            statsd.Invocations.Clear();

            // Both buffers are at capacity, write a new trace
            agent.WriteTrace(CreateTrace(2));

            // Buffers shouldn't have swapped since the reserve buffer was full
            Assert.True(agent.ActiveBuffer == agent.BackBuffer);

            // Both buffers should be full with 1 trace stored
            Assert.True(agent.FrontBuffer.IsFull);
            Assert.Equal(1, agent.FrontBuffer.TraceCount);
            Assert.Equal(1, agent.FrontBuffer.SpanCount);
            Assert.True(agent.BackBuffer.IsFull);
            Assert.Equal(1, agent.BackBuffer.TraceCount);
            Assert.Equal(1, agent.BackBuffer.SpanCount);

            // Dropped trace should have been reported to statsd
            statsd.Verify(s => s.Increment(TracerMetricNames.Queue.EnqueuedTraces, 1, 1, null), Times.Once);
            statsd.Verify(s => s.Increment(TracerMetricNames.Queue.EnqueuedSpans, 2, 1, null), Times.Once);
            statsd.Verify(s => s.Increment(TracerMetricNames.Queue.DroppedTraces, 1, 1, null), Times.Once);
            statsd.Verify(s => s.Increment(TracerMetricNames.Queue.DroppedSpans, 2, 1, null), Times.Once);
            statsd.VerifyNoOtherCalls();
        }
Esempio n. 23
0
        public void To(AgentWriter writer)
        {
            using var signStream = new MemoryStream();
            using var signWriter = new AgentWriter(signStream);
            signWriter.EncodeString(_key.KeyData);
            signWriter.EncodeString(_data);
            signWriter.Write((uint)0);
            var signData = signStream.ToArray();

            writer.Write((uint)(1 + signData.Length));
            writer.Write((byte)AgentMessageType.SSH2_AGENTC_SIGN_REQUEST);
            writer.Write(signData);
        }
Esempio n. 24
0
        public void To(AgentWriter writer)
        {
            using var keyStream = new MemoryStream();
            using var keyWriter = new AgentWriter(keyStream);

            var key = ((KeyHostAlgorithm)_keyFile.HostKey).Key;

            keyWriter.EncodeString(key.ToString());
            switch (key.ToString())
            {
            case "ssh-ed25519":
                var ed25519 = (ED25519Key)key;
                keyWriter.EncodeBignum2(ed25519.PublicKey);
                keyWriter.EncodeBignum2(ed25519.PrivateKey);
                break;

            case "ssh-rsa":
                var rsa = (RsaKey)key;
                keyWriter.EncodeBignum2(rsa.Modulus.ToByteArray().Reverse());
                keyWriter.EncodeBignum2(rsa.Exponent.ToByteArray().Reverse());
                keyWriter.EncodeBignum2(rsa.D.ToByteArray().Reverse());
                keyWriter.EncodeBignum2(rsa.InverseQ.ToByteArray().Reverse());
                keyWriter.EncodeBignum2(rsa.P.ToByteArray().Reverse());
                keyWriter.EncodeBignum2(rsa.Q.ToByteArray().Reverse());
                break;

            case "ecdsa-sha2-nistp256":
            // Fallthrough
            case "ecdsa-sha2-nistp384":
            // Fallthrough
            case "ecdsa-sha2-nistp521":
                var ecdsa     = (EcdsaKey)key;
                var publicKey = ecdsa.Public;
                keyWriter.EncodeString(publicKey[0].ToByteArray().Reverse());
                keyWriter.EncodeString(publicKey[1].ToByteArray().Reverse());
                keyWriter.EncodeBignum2(ecdsa.PrivateKey.ToBigInteger2().ToByteArray().Reverse());
                break;
            }
            // comment
            keyWriter.EncodeString(key.Comment ?? "");
            var keyData = keyStream.ToArray();

            writer.Write((uint)(1 + keyData.Length));
            writer.Write((byte)AgentMessageType.SSH2_AGENTC_ADD_IDENTITY);
            writer.Write(keyData);
        }
Esempio n. 25
0
        public void To(AgentWriter writer)
        {
            if (_agentKey is null)
            {
                writer.Write((uint)1);
                writer.Write((byte)AgentMessageType.SSH2_AGENTC_REMOVE_ALL_IDENTITIES);
                return;
            }

            using var keyStream = new MemoryStream();
            using var keyWriter = new AgentWriter(keyStream);
            keyWriter.EncodeString(_agentKey.KeyData);
            var keyData = keyStream.ToArray();

            writer.Write((uint)(1 + keyData.Length));
            writer.Write((byte)AgentMessageType.SSH2_AGENTC_REMOVE_IDENTITY);
            writer.Write(keyData);
        }
        public void AgentWriterEnqueueFlushTasks()
        {
            var api         = new Mock <IApi>();
            var agentWriter = new AgentWriter(api.Object, statsd: null, automaticFlush: false);
            var flushTcs    = new TaskCompletionSource <bool>();
            int invocation  = 0;

            api.Setup(i => i.SendTracesAsync(It.IsAny <ArraySegment <byte> >(), It.IsAny <int>()))
            .Returns(() =>
            {
                // One for the front buffer, one for the back buffer
                if (Interlocked.Increment(ref invocation) <= 2)
                {
                    return(flushTcs.Task);
                }

                return(Task.FromResult(true));
            });

            var trace = new ArraySegment <Span>(new[] { new Span(new SpanContext(1, 1), DateTimeOffset.UtcNow) });

            // Write trace to the front buffer
            agentWriter.WriteTrace(trace);

            // Flush front buffer
            var firstFlush = agentWriter.FlushTracesAsync();

            // This will swap to the back buffer due front buffer is blocked.
            agentWriter.WriteTrace(trace);

            // Flush the second buffer
            var secondFlush = agentWriter.FlushTracesAsync();

            // This trace will force other buffer swap and then a drop because both buffers are blocked
            agentWriter.WriteTrace(trace);

            // This will try to flush the front buffer again.
            var thirdFlush = agentWriter.FlushTracesAsync();

            // Third flush should wait for the first flush to complete.
            Assert.False(thirdFlush.IsCompleted);
        }
        public Task WakeUpSerializationTask()
        {
            var agent = new AgentWriter(Mock.Of <IApi>(), statsd: null, batchInterval: 0);

            // To reduce flackyness, first we make sure the serialization thread is started
            WaitForDequeue(agent);

            // Wait for the serialization thread to go to sleep
            while (true)
            {
                if (!WaitForDequeue(agent, wakeUpThread: false, delay: 500))
                {
                    break;
                }
            }

            // Serialization thread is asleep, makes sure it wakes up when enqueuing a trace
            agent.WriteTrace(CreateTrace(1));
            Assert.True(WaitForDequeue(agent));

            return(agent.FlushAndCloseAsync());
        }
 public CIAgentWriter(IApi api, int maxBufferSize = DefaultMaxBufferSize)
 {
     _agentWriter = new AgentWriter(api, null, maxBufferSize: maxBufferSize);
 }
Esempio n. 29
0
 public void To(AgentWriter writer)
 {
     writer.Write((uint)1);
     writer.Write((byte)AgentMessageType.SSH2_AGENTC_REQUEST_IDENTITIES);
 }