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()); }
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(); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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(); }
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); }
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); }
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); }
public void To(AgentWriter writer) { writer.Write((uint)1); writer.Write((byte)AgentMessageType.SSH2_AGENTC_REQUEST_IDENTITIES); }