public async Task ShutdownOnNotEmptyQueueFullFlush() { const int batchSize = 2; int exportCalledCount = 0; var spanExporter = new TestSpanExporter(_ => Interlocked.Increment(ref exportCalledCount)); using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, TimeSpan.FromMilliseconds(100), batchSize); var spans = new List <SpanSdk>(); for (int i = 0; i < 100; i++) { spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor)); } Assert.True(spanExporter.ExportedSpans.Length < spans.Count); using (var cts = new CancellationTokenSource(DefaultTimeout)) { await spanProcessor.ShutdownAsync(cts.Token); } Assert.True(spanExporter.WasShutDown); Assert.Equal(spans.Count, spanExporter.ExportedSpans.Length); Assert.InRange(exportCalledCount, spans.Count / batchSize, spans.Count); }
public void ExportMoreSpansThanTheMaxBatchSize() { int exportCalledCount = 0; var spanExporter = new TestExporter(_ => Interlocked.Increment(ref exportCalledCount)); using (var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 3)) { var span1 = CreateSampledEndedSpan(SpanName1, spanProcessor); var span2 = CreateSampledEndedSpan(SpanName1, spanProcessor); var span3 = CreateSampledEndedSpan(SpanName1, spanProcessor); var span4 = CreateSampledEndedSpan(SpanName1, spanProcessor); var span5 = CreateSampledEndedSpan(SpanName1, spanProcessor); var span6 = CreateSampledEndedSpan(SpanName1, spanProcessor); var exported = WaitForSpans(spanExporter, 6, DefaultTimeout); Assert.InRange(exportCalledCount, 2, 6); Assert.Equal(6, exported.Count()); Assert.Contains(span1, exported); Assert.Contains(span2, exported); Assert.Contains(span3, exported); Assert.Contains(span4, exported); Assert.Contains(span5, exported); Assert.Contains(span6, exported); } }
public void ProcessorDoesNotBlockOnExporter() { var spanExporter = new TestExporter(_ => Thread.Sleep(500)); using (var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 128)) { var tracer = TracerFactory.Create(b => b .SetProcessor(e => spanProcessor)) .GetTracer(null); var context = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded); var span = (Span)tracer.StartSpan("foo", context); // does not block var sw = Stopwatch.StartNew(); span.End(); sw.Stop(); Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100)); var exported = WaitForSpans(spanExporter, 1, DefaultTimeout); Assert.Single(exported); } }
public async Task ShutdownOnNotEmptyQueueNotFullFlush() { const int batchSize = 2; int exportCalledCount = 0; // we'll need about 1.5 sec to export all spans // we export 100 spans in batches of 2, each export takes 30ms, in one thread var spanExporter = new TestSpanExporter(_ => { Interlocked.Increment(ref exportCalledCount); Thread.Sleep(30); }); using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, TimeSpan.FromMilliseconds(100), batchSize); var spans = new List <SpanSdk>(); for (int i = 0; i < 100; i++) { spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor)); } Assert.True(spanExporter.ExportedSpans.Length < spans.Count); // we won't bs able to export all before cancellation will fire using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(200))) { await spanProcessor.ShutdownAsync(cts.Token); } var exportedCount = spanExporter.ExportedSpans.Length; Assert.True(exportedCount < spans.Count); }
public void ProcessorDoesNotBlockOnExporter() { spanExporter = new TestExporter(_ => Thread.Sleep(500)); spanProcessor = new BatchingSpanProcessor(spanExporter); var sampledActivity = new Activity("foo"); sampledActivity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; sampledActivity.SetIdFormat(ActivityIdFormat.W3C); sampledActivity.Start(); var span = new Span( sampledActivity, Tracestate.Empty, SpanKind.Internal, TraceConfig.Default, spanProcessor, PreciseTimestamp.GetUtcNow(), default); // does not block var sw = Stopwatch.StartNew(); span.End(); sw.Stop(); Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100)); var exported = WaitForSpans(spanExporter, 1, TimeSpan.FromMilliseconds(600)); Assert.Single(exported); }
public void ExportMoreSpansThanTheMaxBatchSize() { int exportCalledCount = 0; spanExporter = new TestExporter(_ => Interlocked.Increment(ref exportCalledCount)); spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 3); var span1 = CreateSampledEndedSpan(SpanName1); var span2 = CreateSampledEndedSpan(SpanName1); var span3 = CreateSampledEndedSpan(SpanName1); var span4 = CreateSampledEndedSpan(SpanName1); var span5 = CreateSampledEndedSpan(SpanName1); var span6 = CreateSampledEndedSpan(SpanName1); var exported = WaitForSpans(spanExporter, 6, TimeSpan.FromMilliseconds(100)); Assert.Equal(2, exportCalledCount); Assert.Equal(6, exported.Count()); Assert.Contains(span1, exported); Assert.Contains(span2, exported); Assert.Contains(span3, exported); Assert.Contains(span4, exported); Assert.Contains(span5, exported); Assert.Contains(span6, exported); }
public void ExportMoreSpansThanTheMaxBatchSize() { var exporterCalled = new ManualResetEvent(false); int exportCalledCount = 0; var spanExporter = new TestSpanExporter(_ => { exporterCalled.Set(); Interlocked.Increment(ref exportCalledCount); }); using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 3); var span1 = this.CreateSampledEndedSpan(SpanName1, spanProcessor); var span2 = this.CreateSampledEndedSpan(SpanName1, spanProcessor); var span3 = this.CreateSampledEndedSpan(SpanName1, spanProcessor); var span4 = this.CreateSampledEndedSpan(SpanName1, spanProcessor); var span5 = this.CreateSampledEndedSpan(SpanName1, spanProcessor); var span6 = this.CreateSampledEndedSpan(SpanName1, spanProcessor); // wait for exporter to be called to stabilize tests on the build server exporterCalled.WaitOne(TimeSpan.FromSeconds(10)); var exported = this.WaitForSpans(spanExporter, 6, DefaultTimeout); Assert.InRange(exportCalledCount, 2, 6); Assert.Equal(6, exported.Count()); Assert.Contains(new SpanData(span1), exported); Assert.Contains(new SpanData(span2), exported); Assert.Contains(new SpanData(span3), exported); Assert.Contains(new SpanData(span4), exported); Assert.Contains(new SpanData(span5), exported); Assert.Contains(new SpanData(span6), exported); }
public void ExporterIsSlowerThanDelay() { var exportStartTimes = new List <long>(); var exportEndTimes = new List <long>(); var spanExporter = new TestSpanExporter(_ => { exportStartTimes.Add(Stopwatch.GetTimestamp()); Thread.Sleep(50); exportEndTimes.Add(Stopwatch.GetTimestamp()); }); using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, TimeSpan.FromMilliseconds(30), 2); var spans = new List <SpanSdk>(); for (int i = 0; i < 20; i++) { spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor)); } var exported = this.WaitForSpans(spanExporter, 20, TimeSpan.FromSeconds(2)); Assert.Equal(spans.Count, exported.Length); Assert.InRange(exportStartTimes.Count, 10, 20); for (int i = 1; i < exportStartTimes.Count - 1; i++) { Assert.InRange(exportStartTimes[i], exportEndTimes[i - 1] + 1, exportStartTimes[i + 1] - 1); } }
internal Tracing() { TraceConfig = TraceConfig.Default; SpanProcessor = new BatchingSpanProcessor(new NoopSpanExporter()); tracer = new Tracer(SpanProcessor, TraceConfig); }
public async Task ShutdownTwice() { using var spanProcessor = new BatchingSpanProcessor(new TestSpanExporter(null)); await spanProcessor.ShutdownAsync(CancellationToken.None); // does not throw await spanProcessor.ShutdownAsync(CancellationToken.None); }
public async Task ShutdownTwice() { using (var spanProcessor = new BatchingSpanProcessor(new NoopSpanExporter())) { await spanProcessor.ShutdownAsync(CancellationToken.None); // does not throw await spanProcessor.ShutdownAsync(CancellationToken.None); } }
public void ExportDifferentSampledSpans() { var spanExporter = new TestSpanExporter(null); using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 128); var span1 = this.CreateSampledEndedSpan(SpanName1, spanProcessor); var span2 = this.CreateSampledEndedSpan(SpanName2, spanProcessor); var exported = this.WaitForSpans(spanExporter, 2, DefaultTimeout); Assert.Equal(2, exported.Length); Assert.Contains(new SpanData(span1), exported); Assert.Contains(new SpanData(span2), exported); }
public async Task ShutdownWithHugeScheduleDelay() { spanProcessor = new BatchingSpanProcessor(new NoopSpanExporter(), 128, TimeSpan.FromMinutes(1), 32); var sw = Stopwatch.StartNew(); using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(100))) { cts.Token.ThrowIfCancellationRequested(); await spanProcessor.ShutdownAsync(cts.Token).ConfigureAwait(false); } sw.Stop(); Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100)); }
public void DisposeFlushes() { const int batchSize = 2; int exportCalledCount = 0; var spanExporter = new TestExporter(_ => Interlocked.Increment(ref exportCalledCount)); var spans = new List <SpanSdk>(); using (var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, TimeSpan.FromMilliseconds(100), batchSize)) { for (int i = 0; i < 100; i++) { spans.Add(CreateSampledEndedSpan(i.ToString(), spanProcessor)); } Assert.True(spanExporter.ExportedSpans.Length < spans.Count); } Assert.True(spanExporter.WasShutDown); Assert.Equal(spans.Count, spanExporter.ExportedSpans.Length); Assert.Equal(spans.Count / batchSize, exportCalledCount); }
public void AddSpanAfterQueueIsExhausted() { int exportCalledCount = 0; var spanExporter = new TestSpanExporter(_ => Interlocked.Increment(ref exportCalledCount)); using var spanProcessor = new BatchingSpanProcessor(spanExporter, 1, TimeSpan.FromMilliseconds(100), 1); var spans = new List <SpanSdk>(); for (int i = 0; i < 20; i++) { spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor)); } var exported = this.WaitForSpans(spanExporter, 1, DefaultTimeout); Assert.Equal(1, exportCalledCount); Assert.InRange(exported.Length, 1, 2); Assert.Contains(new SpanData(spans.First()), exported); }
internal SpanProcessor Build() { this.Processors = new List <SpanProcessor>(); SpanProcessor exportingProcessor = null; // build or create default exporting processor if (this.lastProcessorFactory != null) { exportingProcessor = this.lastProcessorFactory.Invoke(this.Exporter); this.Processors.Add(exportingProcessor); } else if (this.Exporter != null) { exportingProcessor = new BatchingSpanProcessor(this.Exporter); this.Processors.Add(exportingProcessor); } if (this.processorChain == null) { // if there is no chain, return exporting processor. if (exportingProcessor == null) { exportingProcessor = new NoopSpanProcessor(); this.Processors.Add(exportingProcessor); } return(exportingProcessor); } var next = exportingProcessor; // build chain from the end to the beginning for (int i = this.processorChain.Count - 1; i >= 0; i--) { next = this.processorChain[i].Invoke(next); this.Processors.Add(next); } // return the last processor in the chain - it will be called first return(this.Processors[this.Processors.Count - 1]); }
public void ExportNotSampledSpans() { int exportCalledCount = 0; var spanExporter = new TestExporter(_ => Interlocked.Increment(ref exportCalledCount)); using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 3); var span1 = this.CreateNotSampledEndedSpan(SpanName1, spanProcessor); var span2 = this.CreateSampledEndedSpan(SpanName2, spanProcessor); // Spans are recorded and exported in the same order as they are ended, we test that a non // sampled span is not exported by creating and ending a sampled span after a non sampled span // and checking that the first exported span is the sampled span (the non sampled did not get // exported). var exported = this.WaitForSpans(spanExporter, 1, DefaultTimeout); Assert.Equal(1, exportCalledCount); // Need to check this because otherwise the variable span1 is unused, other option is to not // have a span1 variable. Assert.Single(exported); Assert.Contains(new SpanData(span2), exported); }
public BatchingSpanProcessorTest() { spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 128); }
static Tracing() { TracerConfiguration = new TracerConfiguration(); SpanProcessor = new BatchingSpanProcessor(new NoopSpanExporter()); tracerFactory = new TracerFactory(SpanProcessor, TracerConfiguration); }