Add option to export unsampled spans from span processors (#6057)
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									f4b5bbe829
								
							
						
					
					
						commit
						07351a2e9f
					
				|  | @ -1,2 +1,12 @@ | ||||||
| Comparing source compatibility of  against  | Comparing source compatibility of  against  | ||||||
| No changes. | ***  MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder  (not serializable) | ||||||
|  | 	===  CLASS FILE FORMAT VERSION: 52.0 <- 52.0 | ||||||
|  | 	+++  NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder setExportUnsampledSpans(boolean) | ||||||
|  | ***  MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.SimpleSpanProcessor  (not serializable) | ||||||
|  | 	===  CLASS FILE FORMAT VERSION: 52.0 <- 52.0 | ||||||
|  | 	+++  NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder builder(io.opentelemetry.sdk.trace.export.SpanExporter) | ||||||
|  | +++  NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder  (not serializable) | ||||||
|  | 	+++  CLASS FILE FORMAT VERSION: 52.0 <- n.a. | ||||||
|  | 	+++  NEW SUPERCLASS: java.lang.Object | ||||||
|  | 	+++  NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessor build() | ||||||
|  | 	+++  NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder setExportUnsampledSpans(boolean) | ||||||
|  |  | ||||||
|  | @ -415,7 +415,7 @@ class OpenTelemetrySdkTest { | ||||||
|                 + "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, " |                 + "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, " | ||||||
|                 + "spanLimitsSupplier=SpanLimitsValue{maxNumberOfAttributes=128, maxNumberOfEvents=128, maxNumberOfLinks=128, maxNumberOfAttributesPerEvent=128, maxNumberOfAttributesPerLink=128, maxAttributeValueLength=2147483647}, " |                 + "spanLimitsSupplier=SpanLimitsValue{maxNumberOfAttributes=128, maxNumberOfEvents=128, maxNumberOfLinks=128, maxNumberOfAttributesPerEvent=128, maxNumberOfAttributesPerLink=128, maxAttributeValueLength=2147483647}, " | ||||||
|                 + "sampler=ParentBased{root:AlwaysOnSampler,remoteParentSampled:AlwaysOnSampler,remoteParentNotSampled:AlwaysOffSampler,localParentSampled:AlwaysOnSampler,localParentNotSampled:AlwaysOffSampler}, " |                 + "sampler=ParentBased{root:AlwaysOnSampler,remoteParentSampled:AlwaysOnSampler,remoteParentNotSampled:AlwaysOffSampler,localParentSampled:AlwaysOnSampler,localParentNotSampled:AlwaysOffSampler}, " | ||||||
|                 + "spanProcessor=SimpleSpanProcessor{spanExporter=MultiSpanExporter{spanExporters=[MockSpanExporter{}, MockSpanExporter{}]}}" |                 + "spanProcessor=SimpleSpanProcessor{spanExporter=MultiSpanExporter{spanExporters=[MockSpanExporter{}, MockSpanExporter{}]}, exportUnsampledSpans=false}" | ||||||
|                 + "}, " |                 + "}, " | ||||||
|                 + "meterProvider=SdkMeterProvider{" |                 + "meterProvider=SdkMeterProvider{" | ||||||
|                 + "clock=SystemClock{}, " |                 + "clock=SystemClock{}, " | ||||||
|  |  | ||||||
|  | @ -53,6 +53,7 @@ public final class BatchSpanProcessor implements SpanProcessor { | ||||||
|       AttributeKey.booleanKey("dropped"); |       AttributeKey.booleanKey("dropped"); | ||||||
|   private static final String SPAN_PROCESSOR_TYPE_VALUE = BatchSpanProcessor.class.getSimpleName(); |   private static final String SPAN_PROCESSOR_TYPE_VALUE = BatchSpanProcessor.class.getSimpleName(); | ||||||
| 
 | 
 | ||||||
|  |   private final boolean exportUnsampledSpans; | ||||||
|   private final Worker worker; |   private final Worker worker; | ||||||
|   private final AtomicBoolean isShutdown = new AtomicBoolean(false); |   private final AtomicBoolean isShutdown = new AtomicBoolean(false); | ||||||
| 
 | 
 | ||||||
|  | @ -69,11 +70,13 @@ public final class BatchSpanProcessor implements SpanProcessor { | ||||||
| 
 | 
 | ||||||
|   BatchSpanProcessor( |   BatchSpanProcessor( | ||||||
|       SpanExporter spanExporter, |       SpanExporter spanExporter, | ||||||
|  |       boolean exportUnsampledSpans, | ||||||
|       MeterProvider meterProvider, |       MeterProvider meterProvider, | ||||||
|       long scheduleDelayNanos, |       long scheduleDelayNanos, | ||||||
|       int maxQueueSize, |       int maxQueueSize, | ||||||
|       int maxExportBatchSize, |       int maxExportBatchSize, | ||||||
|       long exporterTimeoutNanos) { |       long exporterTimeoutNanos) { | ||||||
|  |     this.exportUnsampledSpans = exportUnsampledSpans; | ||||||
|     this.worker = |     this.worker = | ||||||
|         new Worker( |         new Worker( | ||||||
|             spanExporter, |             spanExporter, | ||||||
|  | @ -96,11 +99,10 @@ public final class BatchSpanProcessor implements SpanProcessor { | ||||||
| 
 | 
 | ||||||
|   @Override |   @Override | ||||||
|   public void onEnd(ReadableSpan span) { |   public void onEnd(ReadableSpan span) { | ||||||
|     if (span == null || !span.getSpanContext().isSampled()) { |     if (span != null && (exportUnsampledSpans || span.getSpanContext().isSampled())) { | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|       worker.addSpan(span); |       worker.addSpan(span); | ||||||
|     } |     } | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   @Override |   @Override | ||||||
|   public boolean isEndRequired() { |   public boolean isEndRequired() { | ||||||
|  | @ -135,6 +137,8 @@ public final class BatchSpanProcessor implements SpanProcessor { | ||||||
|     return "BatchSpanProcessor{" |     return "BatchSpanProcessor{" | ||||||
|         + "spanExporter=" |         + "spanExporter=" | ||||||
|         + worker.spanExporter |         + worker.spanExporter | ||||||
|  |         + ", exportUnsampledSpans=" | ||||||
|  |         + exportUnsampledSpans | ||||||
|         + ", scheduleDelayNanos=" |         + ", scheduleDelayNanos=" | ||||||
|         + worker.scheduleDelayNanos |         + worker.scheduleDelayNanos | ||||||
|         + ", maxExportBatchSize=" |         + ", maxExportBatchSize=" | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ public final class BatchSpanProcessorBuilder { | ||||||
|   static final int DEFAULT_EXPORT_TIMEOUT_MILLIS = 30_000; |   static final int DEFAULT_EXPORT_TIMEOUT_MILLIS = 30_000; | ||||||
| 
 | 
 | ||||||
|   private final SpanExporter spanExporter; |   private final SpanExporter spanExporter; | ||||||
|  |   private boolean exportUnsampledSpans; | ||||||
|   private long scheduleDelayNanos = TimeUnit.MILLISECONDS.toNanos(DEFAULT_SCHEDULE_DELAY_MILLIS); |   private long scheduleDelayNanos = TimeUnit.MILLISECONDS.toNanos(DEFAULT_SCHEDULE_DELAY_MILLIS); | ||||||
|   private int maxQueueSize = DEFAULT_MAX_QUEUE_SIZE; |   private int maxQueueSize = DEFAULT_MAX_QUEUE_SIZE; | ||||||
|   private int maxExportBatchSize = DEFAULT_MAX_EXPORT_BATCH_SIZE; |   private int maxExportBatchSize = DEFAULT_MAX_EXPORT_BATCH_SIZE; | ||||||
|  | @ -35,6 +36,15 @@ public final class BatchSpanProcessorBuilder { | ||||||
|     this.spanExporter = requireNonNull(spanExporter, "spanExporter"); |     this.spanExporter = requireNonNull(spanExporter, "spanExporter"); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    * Sets whether unsampled spans should be exported. If unset, defaults to exporting only sampled | ||||||
|  |    * spans. | ||||||
|  |    */ | ||||||
|  |   public BatchSpanProcessorBuilder setExportUnsampledSpans(boolean exportUnsampledSpans) { | ||||||
|  |     this.exportUnsampledSpans = exportUnsampledSpans; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   /** |   /** | ||||||
|    * Sets the delay interval between two consecutive exports. If unset, defaults to {@value |    * Sets the delay interval between two consecutive exports. If unset, defaults to {@value | ||||||
|    * DEFAULT_SCHEDULE_DELAY_MILLIS}ms. |    * DEFAULT_SCHEDULE_DELAY_MILLIS}ms. | ||||||
|  | @ -146,6 +156,7 @@ public final class BatchSpanProcessorBuilder { | ||||||
|   public BatchSpanProcessor build() { |   public BatchSpanProcessor build() { | ||||||
|     return new BatchSpanProcessor( |     return new BatchSpanProcessor( | ||||||
|         spanExporter, |         spanExporter, | ||||||
|  |         exportUnsampledSpans, | ||||||
|         meterProvider, |         meterProvider, | ||||||
|         scheduleDelayNanos, |         scheduleDelayNanos, | ||||||
|         maxQueueSize, |         maxQueueSize, | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ public final class SimpleSpanProcessor implements SpanProcessor { | ||||||
|   private static final Logger logger = Logger.getLogger(SimpleSpanProcessor.class.getName()); |   private static final Logger logger = Logger.getLogger(SimpleSpanProcessor.class.getName()); | ||||||
| 
 | 
 | ||||||
|   private final SpanExporter spanExporter; |   private final SpanExporter spanExporter; | ||||||
|   private final boolean sampled; |   private final boolean exportUnsampledSpans; | ||||||
|   private final Set<CompletableResultCode> pendingExports = |   private final Set<CompletableResultCode> pendingExports = | ||||||
|       Collections.newSetFromMap(new ConcurrentHashMap<>()); |       Collections.newSetFromMap(new ConcurrentHashMap<>()); | ||||||
|   private final AtomicBoolean isShutdown = new AtomicBoolean(false); |   private final AtomicBoolean isShutdown = new AtomicBoolean(false); | ||||||
|  | @ -53,12 +53,17 @@ public final class SimpleSpanProcessor implements SpanProcessor { | ||||||
|    */ |    */ | ||||||
|   public static SpanProcessor create(SpanExporter exporter) { |   public static SpanProcessor create(SpanExporter exporter) { | ||||||
|     requireNonNull(exporter, "exporter"); |     requireNonNull(exporter, "exporter"); | ||||||
|     return new SimpleSpanProcessor(exporter, /* sampled= */ true); |     return builder(exporter).build(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   SimpleSpanProcessor(SpanExporter spanExporter, boolean sampled) { |   public static SimpleSpanProcessorBuilder builder(SpanExporter exporter) { | ||||||
|  |     requireNonNull(exporter, "exporter"); | ||||||
|  |     return new SimpleSpanProcessorBuilder(exporter); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   SimpleSpanProcessor(SpanExporter spanExporter, boolean exportUnsampledSpans) { | ||||||
|     this.spanExporter = requireNonNull(spanExporter, "spanExporter"); |     this.spanExporter = requireNonNull(spanExporter, "spanExporter"); | ||||||
|     this.sampled = sampled; |     this.exportUnsampledSpans = exportUnsampledSpans; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   @Override |   @Override | ||||||
|  | @ -73,9 +78,7 @@ public final class SimpleSpanProcessor implements SpanProcessor { | ||||||
| 
 | 
 | ||||||
|   @Override |   @Override | ||||||
|   public void onEnd(ReadableSpan span) { |   public void onEnd(ReadableSpan span) { | ||||||
|     if (sampled && !span.getSpanContext().isSampled()) { |     if (span != null && (exportUnsampledSpans || span.getSpanContext().isSampled())) { | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|       try { |       try { | ||||||
|         List<SpanData> spans = Collections.singletonList(span.toSpanData()); |         List<SpanData> spans = Collections.singletonList(span.toSpanData()); | ||||||
|         CompletableResultCode result = spanExporter.export(spans); |         CompletableResultCode result = spanExporter.export(spans); | ||||||
|  | @ -91,6 +94,7 @@ public final class SimpleSpanProcessor implements SpanProcessor { | ||||||
|         logger.log(Level.WARNING, "Exporter threw an Exception", e); |         logger.log(Level.WARNING, "Exporter threw an Exception", e); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   @Override |   @Override | ||||||
|   public boolean isEndRequired() { |   public boolean isEndRequired() { | ||||||
|  | @ -128,6 +132,11 @@ public final class SimpleSpanProcessor implements SpanProcessor { | ||||||
| 
 | 
 | ||||||
|   @Override |   @Override | ||||||
|   public String toString() { |   public String toString() { | ||||||
|     return "SimpleSpanProcessor{" + "spanExporter=" + spanExporter + '}'; |     return "SimpleSpanProcessor{" | ||||||
|  |         + "spanExporter=" | ||||||
|  |         + spanExporter | ||||||
|  |         + ", exportUnsampledSpans=" | ||||||
|  |         + exportUnsampledSpans | ||||||
|  |         + '}'; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,36 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright The OpenTelemetry Authors | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package io.opentelemetry.sdk.trace.export; | ||||||
|  | 
 | ||||||
|  | import static java.util.Objects.requireNonNull; | ||||||
|  | 
 | ||||||
|  | /** Builder class for {@link SimpleSpanProcessor}. */ | ||||||
|  | public final class SimpleSpanProcessorBuilder { | ||||||
|  |   private final SpanExporter spanExporter; | ||||||
|  |   private boolean exportUnsampledSpans; | ||||||
|  | 
 | ||||||
|  |   SimpleSpanProcessorBuilder(SpanExporter spanExporter) { | ||||||
|  |     this.spanExporter = requireNonNull(spanExporter, "spanExporter"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** | ||||||
|  |    * Sets whether unsampled spans should be exported. If unset, defaults to exporting only sampled | ||||||
|  |    * spans. | ||||||
|  |    */ | ||||||
|  |   public SimpleSpanProcessorBuilder setExportUnsampledSpans(boolean exportUnsampledSpans) { | ||||||
|  |     this.exportUnsampledSpans = exportUnsampledSpans; | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** | ||||||
|  |    * Returns a new {@link SimpleSpanProcessor} with the configuration of this builder. | ||||||
|  |    * | ||||||
|  |    * @return a new {@link SimpleSpanProcessor}. | ||||||
|  |    */ | ||||||
|  |   public SimpleSpanProcessor build() { | ||||||
|  |     return new SimpleSpanProcessor(spanExporter, exportUnsampledSpans); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -517,6 +517,38 @@ class BatchSpanProcessorTest { | ||||||
|     assertThat(exported).containsExactly(span.toSpanData()); |     assertThat(exported).containsExactly(span.toSpanData()); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   @Test | ||||||
|  |   void exportUnsampledSpans_recordOnly() { | ||||||
|  |     WaitingSpanExporter waitingSpanExporter = | ||||||
|  |         new WaitingSpanExporter(1, CompletableResultCode.ofSuccess()); | ||||||
|  | 
 | ||||||
|  |     when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList())) | ||||||
|  |         .thenReturn(SamplingResult.recordOnly()); | ||||||
|  |     sdkTracerProvider = | ||||||
|  |         SdkTracerProvider.builder() | ||||||
|  |             .addSpanProcessor( | ||||||
|  |                 BatchSpanProcessor.builder(waitingSpanExporter) | ||||||
|  |                     .setExportUnsampledSpans(true) | ||||||
|  |                     .setScheduleDelay(MAX_SCHEDULE_DELAY_MILLIS, TimeUnit.MILLISECONDS) | ||||||
|  |                     .build()) | ||||||
|  |             .setSampler(mockSampler) | ||||||
|  |             .build(); | ||||||
|  | 
 | ||||||
|  |     ReadableSpan span1 = createEndedSpan(SPAN_NAME_1); | ||||||
|  |     when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList())) | ||||||
|  |         .thenReturn(SamplingResult.recordAndSample()); | ||||||
|  |     ReadableSpan span2 = createEndedSpan(SPAN_NAME_2); | ||||||
|  | 
 | ||||||
|  |     // Spans are recorded and exported in the same order as they are ended, we test that a non | ||||||
|  |     // exported 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). | ||||||
|  |     List<SpanData> exported = waitingSpanExporter.waitForExport(); | ||||||
|  |     // Need to check this because otherwise the variable span1 is unused, other option is to not | ||||||
|  |     // have a span1 variable. | ||||||
|  |     assertThat(exported).containsExactly(span1.toSpanData(), span2.toSpanData()); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   @Test |   @Test | ||||||
|   @Timeout(10) |   @Timeout(10) | ||||||
|   @SuppressLogger(SdkTracerProvider.class) |   @SuppressLogger(SdkTracerProvider.class) | ||||||
|  | @ -569,6 +601,7 @@ class BatchSpanProcessorTest { | ||||||
|         .hasToString( |         .hasToString( | ||||||
|             "BatchSpanProcessor{" |             "BatchSpanProcessor{" | ||||||
|                 + "spanExporter=mockSpanExporter, " |                 + "spanExporter=mockSpanExporter, " | ||||||
|  |                 + "exportUnsampledSpans=false, " | ||||||
|                 + "scheduleDelayNanos=5000000000, " |                 + "scheduleDelayNanos=5000000000, " | ||||||
|                 + "maxExportBatchSize=512, " |                 + "maxExportBatchSize=512, " | ||||||
|                 + "exporterTimeoutNanos=30000000000}"); |                 + "exporterTimeoutNanos=30000000000}"); | ||||||
|  |  | ||||||
|  | @ -59,7 +59,12 @@ class SimpleSpanProcessorTest { | ||||||
|           SpanId.getInvalid(), |           SpanId.getInvalid(), | ||||||
|           TraceFlags.getSampled(), |           TraceFlags.getSampled(), | ||||||
|           TraceState.getDefault()); |           TraceState.getDefault()); | ||||||
|   private static final SpanContext NOT_SAMPLED_SPAN_CONTEXT = SpanContext.getInvalid(); |   private static final SpanContext NOT_SAMPLED_SPAN_CONTEXT = | ||||||
|  |       SpanContext.create( | ||||||
|  |           TraceId.getInvalid(), | ||||||
|  |           SpanId.getInvalid(), | ||||||
|  |           TraceFlags.getDefault(), | ||||||
|  |           TraceState.getDefault()); | ||||||
| 
 | 
 | ||||||
|   private SpanProcessor simpleSampledSpansProcessor; |   private SpanProcessor simpleSampledSpansProcessor; | ||||||
| 
 | 
 | ||||||
|  | @ -100,29 +105,29 @@ class SimpleSpanProcessorTest { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   @Test |   @Test | ||||||
|   void onEndSync_OnlySampled_NotSampledSpan() { |   void onEndSync_ExportUnsampledSpans_NotSampledSpan() { | ||||||
|  |     SpanData spanData = TestUtils.makeBasicSpan(); | ||||||
|     when(readableSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT); |     when(readableSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT); | ||||||
|     when(readableSpan.toSpanData()) |     when(readableSpan.toSpanData()).thenReturn(spanData); | ||||||
|         .thenReturn(TestUtils.makeBasicSpan()) |     SpanProcessor simpleSpanProcessor = | ||||||
|         .thenThrow(new RuntimeException()); |         SimpleSpanProcessor.builder(spanExporter).setExportUnsampledSpans(true).build(); | ||||||
|     SpanProcessor simpleSpanProcessor = SimpleSpanProcessor.create(spanExporter); |  | ||||||
|     simpleSpanProcessor.onEnd(readableSpan); |     simpleSpanProcessor.onEnd(readableSpan); | ||||||
|     verifyNoInteractions(spanExporter); |     verify(spanExporter).export(Collections.singletonList(spanData)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   @Test |   @Test | ||||||
|   void onEndSync_OnlySampled_SampledSpan() { |   void onEndSync_ExportUnsampledSpans_SampledSpan() { | ||||||
|  |     SpanData spanData = TestUtils.makeBasicSpan(); | ||||||
|     when(readableSpan.getSpanContext()).thenReturn(SAMPLED_SPAN_CONTEXT); |     when(readableSpan.getSpanContext()).thenReturn(SAMPLED_SPAN_CONTEXT); | ||||||
|     when(readableSpan.toSpanData()) |     when(readableSpan.toSpanData()).thenReturn(spanData); | ||||||
|         .thenReturn(TestUtils.makeBasicSpan()) |     SpanProcessor simpleSpanProcessor = | ||||||
|         .thenThrow(new RuntimeException()); |         SimpleSpanProcessor.builder(spanExporter).setExportUnsampledSpans(true).build(); | ||||||
|     SpanProcessor simpleSpanProcessor = SimpleSpanProcessor.create(spanExporter); |  | ||||||
|     simpleSpanProcessor.onEnd(readableSpan); |     simpleSpanProcessor.onEnd(readableSpan); | ||||||
|     verify(spanExporter).export(Collections.singletonList(TestUtils.makeBasicSpan())); |     verify(spanExporter).export(Collections.singletonList(spanData)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   @Test |   @Test | ||||||
|   void tracerSdk_NotSampled_Span() { |   void tracerSdk_SampledSpan() { | ||||||
|     WaitingSpanExporter waitingSpanExporter = |     WaitingSpanExporter waitingSpanExporter = | ||||||
|         new WaitingSpanExporter(1, CompletableResultCode.ofSuccess()); |         new WaitingSpanExporter(1, CompletableResultCode.ofSuccess()); | ||||||
| 
 | 
 | ||||||
|  | @ -159,25 +164,43 @@ class SimpleSpanProcessorTest { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   @Test |   @Test | ||||||
|   void tracerSdk_NotSampled_RecordingEventsSpan() { |   void tracerSdk_ExportUnsampledSpans_NotSampledSpan() { | ||||||
|     // TODO(bdrutu): Fix this when Sampler return RECORD_ONLY option. |     WaitingSpanExporter waitingSpanExporter = | ||||||
|     /* |         new WaitingSpanExporter(1, CompletableResultCode.ofSuccess()); | ||||||
|     tracer.addSpanProcessor( |  | ||||||
|         BatchSpanProcessor.builder(waitingSpanExporter) |  | ||||||
|             .setScheduleDelayMillis(MAX_SCHEDULE_DELAY_MILLIS) |  | ||||||
|             .reportOnlySampled(false) |  | ||||||
|             .build()); |  | ||||||
| 
 | 
 | ||||||
|     io.opentelemetry.trace.Span span = |     SdkTracerProvider sdkTracerProvider = | ||||||
|         tracer |         SdkTracerProvider.builder() | ||||||
|             .spanBuilder("FOO") |             .addSpanProcessor( | ||||||
|             .setSampler(Samplers.neverSample()) |                 SimpleSpanProcessor.builder(waitingSpanExporter) | ||||||
|             .startSpanWithSampler(); |                     .setExportUnsampledSpans(true) | ||||||
|  |                     .build()) | ||||||
|  |             .setSampler(mockSampler) | ||||||
|  |             .build(); | ||||||
|  | 
 | ||||||
|  |     when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList())) | ||||||
|  |         .thenReturn(SamplingResult.drop()); | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       Tracer tracer = sdkTracerProvider.get(getClass().getName()); | ||||||
|  |       tracer.spanBuilder(SPAN_NAME).startSpan(); | ||||||
|  |       tracer.spanBuilder(SPAN_NAME).startSpan(); | ||||||
|  | 
 | ||||||
|  |       when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList())) | ||||||
|  |           .thenReturn(SamplingResult.recordOnly()); | ||||||
|  |       Span span = tracer.spanBuilder(SPAN_NAME).startSpan(); | ||||||
|       span.end(); |       span.end(); | ||||||
| 
 | 
 | ||||||
|     List<SpanData> exported = waitingSpanExporter.waitForExport(1); |       // 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). | ||||||
|  |       List<SpanData> exported = waitingSpanExporter.waitForExport(); | ||||||
|  |       // Need to check this because otherwise the variable span1 is unused, other option is to not | ||||||
|  |       // have a span1 variable. | ||||||
|       assertThat(exported).containsExactly(((ReadableSpan) span).toSpanData()); |       assertThat(exported).containsExactly(((ReadableSpan) span).toSpanData()); | ||||||
|     */ |     } finally { | ||||||
|  |       sdkTracerProvider.shutdown(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   @Test |   @Test | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue