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,10 +99,9 @@ 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
|
||||||
|
@ -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,22 +78,21 @@ 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 {
|
||||||
}
|
List<SpanData> spans = Collections.singletonList(span.toSpanData());
|
||||||
try {
|
CompletableResultCode result = spanExporter.export(spans);
|
||||||
List<SpanData> spans = Collections.singletonList(span.toSpanData());
|
pendingExports.add(result);
|
||||||
CompletableResultCode result = spanExporter.export(spans);
|
result.whenComplete(
|
||||||
pendingExports.add(result);
|
() -> {
|
||||||
result.whenComplete(
|
pendingExports.remove(result);
|
||||||
() -> {
|
if (!result.isSuccess()) {
|
||||||
pendingExports.remove(result);
|
logger.log(Level.FINE, "Exporter failed");
|
||||||
if (!result.isSuccess()) {
|
}
|
||||||
logger.log(Level.FINE, "Exporter failed");
|
});
|
||||||
}
|
} catch (RuntimeException e) {
|
||||||
});
|
logger.log(Level.WARNING, "Exporter threw an Exception", e);
|
||||||
} catch (RuntimeException e) {
|
}
|
||||||
logger.log(Level.WARNING, "Exporter threw an Exception", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
span.end();
|
.build())
|
||||||
|
.setSampler(mockSampler)
|
||||||
|
.build();
|
||||||
|
|
||||||
List<SpanData> exported = waitingSpanExporter.waitForExport(1);
|
when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList()))
|
||||||
assertThat(exported).containsExactly(((ReadableSpan) span).toSpanData());
|
.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();
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
} finally {
|
||||||
|
sdkTracerProvider.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue