Skip to content

Commit a1c0d0b

Browse files
authored
Consistent application of exporter customizers when otel.{signal}.exporter=none (#7017)
1 parent 97410cb commit a1c0d0b

File tree

11 files changed

+240
-269
lines changed

11 files changed

+240
-269
lines changed

sdk-extensions/autoconfigure/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ testing {
7878
environment("OTEL_PROPAGATORS", "tracecontext,baggage,b3,b3multi,jaeger,ottrace,test")
7979
environment("OTEL_EXPORTER_OTLP_HEADERS", "cat=meow,dog=bark")
8080
environment("OTEL_EXPORTER_OTLP_TIMEOUT", "5000")
81-
environment("OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT", "2")
8281
environment("OTEL_TEST_CONFIGURED", "true")
8382
environment("OTEL_TEST_WRAPPED", "1")
8483
}

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,7 @@ static Map<String, LogRecordExporter> configureLogRecordExporters(
4848
throw new ConfigurationException(
4949
"otel.logs.exporter contains " + EXPORTER_NONE + " along with other exporters");
5050
}
51-
LogRecordExporter noop = LogRecordExporter.composite();
52-
LogRecordExporter customized = logRecordExporterCustomizer.apply(noop, config);
53-
if (customized == noop) {
54-
return Collections.emptyMap();
55-
}
56-
closeables.add(customized);
57-
return Collections.singletonMap(EXPORTER_NONE, customized);
51+
return Collections.emptyMap();
5852
}
5953

6054
if (exporterNames.isEmpty()) {

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,7 @@ static Map<String, SpanExporter> configureSpanExporters(
4848
throw new ConfigurationException(
4949
"otel.traces.exporter contains " + EXPORTER_NONE + " along with other exporters");
5050
}
51-
SpanExporter noop = SpanExporter.composite();
52-
SpanExporter customized = spanExporterCustomizer.apply(noop, config);
53-
if (customized == noop) {
54-
return Collections.emptyMap();
55-
}
56-
closeables.add(customized);
57-
return Collections.singletonMap(EXPORTER_NONE, customized);
51+
return Collections.emptyMap();
5852
}
5953

6054
if (exporterNames.isEmpty()) {

sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,13 @@
1111
import static org.assertj.core.api.Assertions.assertThatCode;
1212
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1313
import static org.mockito.ArgumentMatchers.any;
14-
import static org.mockito.ArgumentMatchers.same;
1514
import static org.mockito.Mockito.doReturn;
1615
import static org.mockito.Mockito.doThrow;
1716
import static org.mockito.Mockito.mock;
1817
import static org.mockito.Mockito.never;
1918
import static org.mockito.Mockito.spy;
2019
import static org.mockito.Mockito.times;
2120
import static org.mockito.Mockito.verify;
22-
import static org.mockito.Mockito.verifyNoInteractions;
2321
import static org.mockito.Mockito.verifyNoMoreInteractions;
2422
import static org.mockito.Mockito.when;
2523

@@ -54,14 +52,10 @@
5452
import io.opentelemetry.sdk.resources.Resource;
5553
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
5654
import io.opentelemetry.sdk.trace.IdGenerator;
57-
import io.opentelemetry.sdk.trace.ReadWriteSpan;
58-
import io.opentelemetry.sdk.trace.ReadableSpan;
5955
import io.opentelemetry.sdk.trace.SdkTracerProvider;
6056
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
61-
import io.opentelemetry.sdk.trace.SpanProcessor;
6257
import io.opentelemetry.sdk.trace.data.SpanData;
6358
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
64-
import io.opentelemetry.sdk.trace.export.SpanExporter;
6559
import io.opentelemetry.sdk.trace.samplers.Sampler;
6660
import java.io.IOException;
6761
import java.math.BigDecimal;
@@ -98,8 +92,6 @@ class AutoConfiguredOpenTelemetrySdkTest {
9892
@Mock private TextMapGetter<Map<String, String>> getter;
9993
@Mock private Sampler sampler1;
10094
@Mock private Sampler sampler2;
101-
@Mock private SpanExporter spanExporter1;
102-
@Mock private SpanExporter spanExporter2;
10395
@Mock private MetricReader metricReader;
10496
@Mock private LogRecordProcessor logRecordProcessor;
10597

@@ -247,76 +239,6 @@ void builder_addSamplerCustomizer() {
247239
.isEqualTo(sampler2);
248240
}
249241

250-
@Test
251-
void builder_addSpanExporterCustomizer() {
252-
Mockito.lenient().when(spanExporter2.shutdown()).thenReturn(CompletableResultCode.ofSuccess());
253-
254-
SdkTracerProvider sdkTracerProvider =
255-
builder
256-
.addSpanExporterCustomizer(
257-
(previous, config) -> {
258-
assertThat(previous).isSameAs(SpanExporter.composite());
259-
return spanExporter1;
260-
})
261-
.addSpanExporterCustomizer(
262-
(previous, config) -> {
263-
assertThat(previous).isSameAs(spanExporter1);
264-
return spanExporter2;
265-
})
266-
.build()
267-
.getOpenTelemetrySdk()
268-
.getSdkTracerProvider();
269-
270-
assertThat(sdkTracerProvider)
271-
.extracting("sharedState")
272-
.extracting("activeSpanProcessor")
273-
.extracting("worker")
274-
.extracting("spanExporter")
275-
.isEqualTo(spanExporter2);
276-
}
277-
278-
@Test
279-
void builder_addSpanProcessorCustomizer() {
280-
SpanProcessor mockProcessor1 = Mockito.mock(SpanProcessor.class);
281-
SpanProcessor mockProcessor2 = Mockito.mock(SpanProcessor.class);
282-
when(mockProcessor2.isStartRequired()).thenReturn(true);
283-
when(mockProcessor2.isEndRequired()).thenReturn(true);
284-
Mockito.lenient().doReturn(CompletableResultCode.ofSuccess()).when(mockProcessor2).shutdown();
285-
Mockito.lenient().when(spanExporter1.shutdown()).thenReturn(CompletableResultCode.ofSuccess());
286-
287-
SdkTracerProvider sdkTracerProvider =
288-
builder
289-
.addSpanExporterCustomizer((prev, config) -> spanExporter1)
290-
.addSpanProcessorCustomizer(
291-
(previous, config) -> {
292-
assertThat(previous).isNotSameAs(mockProcessor2);
293-
return mockProcessor1;
294-
})
295-
.addSpanProcessorCustomizer(
296-
(previous, config) -> {
297-
assertThat(previous).isSameAs(mockProcessor1);
298-
return mockProcessor2;
299-
})
300-
.build()
301-
.getOpenTelemetrySdk()
302-
.getSdkTracerProvider();
303-
304-
assertThat(sdkTracerProvider)
305-
.extracting("sharedState")
306-
.extracting("activeSpanProcessor")
307-
.isSameAs(mockProcessor2);
308-
309-
Span span = sdkTracerProvider.get("dummy-scope").spanBuilder("dummy-span").startSpan();
310-
311-
verify(mockProcessor2).onStart(any(), same((ReadWriteSpan) span));
312-
313-
span.end();
314-
verify(mockProcessor2).onEnd(same((ReadableSpan) span));
315-
316-
verifyNoInteractions(mockProcessor1);
317-
verifyNoInteractions(spanExporter1);
318-
}
319-
320242
@Test
321243
void builder_addAutoConfigurationCustomizerProviderUsingComponentLoader() {
322244
AutoConfigurationCustomizerProvider customizerProvider =
@@ -420,8 +342,6 @@ void builder_addMeterProviderCustomizer() {
420342
verify(metricReader).forceFlush();
421343
}
422344

423-
// TODO: add test for addMetricExporterCustomizer once OTLP export is enabled by default
424-
425345
@Test
426346
void builder_addLoggerProviderCustomizer() {
427347
Mockito.lenient()
@@ -442,10 +362,6 @@ void builder_addLoggerProviderCustomizer() {
442362
verify(logRecordProcessor).forceFlush();
443363
}
444364

445-
// TODO: add test for addLogRecordExporterCustomizer once OTLP export is enabled by default
446-
447-
// TODO: add test for addLogRecordProcessorCustomizer once OTLP export is enabled by default
448-
449365
@Test
450366
void builder_setResultAsGlobalFalse() {
451367
GlobalOpenTelemetry.set(OpenTelemetry.noop());

sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java

Lines changed: 55 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
import org.junit.jupiter.api.extension.RegisterExtension;
5454

5555
@SuppressWarnings("InterruptedExceptionSwallowed")
56-
class FullConfigTest {
56+
public class FullConfigTest {
5757

5858
private static final BlockingQueue<ExportTraceServiceRequest> otlpTraceRequests =
5959
new LinkedBlockingDeque<>();
@@ -193,7 +193,6 @@ void configures() throws Exception {
193193
.spanBuilder("test")
194194
.startSpan()
195195
.setAttribute("cat", "meow")
196-
.setAttribute("dog", "bark")
197196
.end();
198197

199198
Meter meter = GlobalOpenTelemetry.get().getMeter("test");
@@ -209,7 +208,6 @@ void configures() throws Exception {
209208

210209
EventLogger eventLogger = GlobalEventLoggerProvider.get().eventLoggerBuilder("test").build();
211210
eventLogger.builder("namespace.test-name").put("cow", "moo").emit();
212-
;
213211

214212
openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS);
215213
openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS);
@@ -218,37 +216,19 @@ void configures() throws Exception {
218216
await().untilAsserted(() -> assertThat(otlpTraceRequests).hasSize(1));
219217

220218
ExportTraceServiceRequest traceRequest = otlpTraceRequests.take();
221-
assertThat(traceRequest.getResourceSpans(0).getResource().getAttributesList())
222-
.contains(
223-
KeyValue.newBuilder()
224-
.setKey("service.name")
225-
.setValue(AnyValue.newBuilder().setStringValue("test").build())
226-
.build(),
227-
KeyValue.newBuilder()
228-
.setKey("cat")
229-
.setValue(AnyValue.newBuilder().setStringValue("meow").build())
230-
.build());
219+
List<KeyValue> spanResourceAttributes =
220+
traceRequest.getResourceSpans(0).getResource().getAttributesList();
221+
assertHasKeyValue(spanResourceAttributes, "service.name", "test");
222+
assertHasKeyValue(spanResourceAttributes, "cat", "meow");
231223
io.opentelemetry.proto.trace.v1.Span span =
232224
traceRequest.getResourceSpans(0).getScopeSpans(0).getSpans(0);
233-
// Dog dropped by attribute limit.
234-
assertThat(span.getAttributesList())
235-
.containsExactlyInAnyOrder(
236-
KeyValue.newBuilder()
237-
.setKey("configured")
238-
.setValue(AnyValue.newBuilder().setBoolValue(true).build())
239-
.build(),
240-
KeyValue.newBuilder()
241-
.setKey("wrapped")
242-
.setValue(AnyValue.newBuilder().setIntValue(1).build())
243-
.build(),
244-
KeyValue.newBuilder()
245-
.setKey("cat")
246-
.setValue(AnyValue.newBuilder().setStringValue("meow").build())
247-
.build());
225+
assertHasKeyValue(span.getAttributesList(), "configured", true);
226+
assertHasKeyValue(span.getAttributesList(), "wrapped", 1);
227+
assertHasKeyValue(span.getAttributesList(), "cat", "meow");
228+
assertHasKeyValue(span.getAttributesList(), "extra-key", "extra-value");
248229

249230
// await on assertions since metrics may come in different order for BatchSpanProcessor,
250-
// exporter, or the ones we
251-
// created in the test.
231+
// exporter, or the ones we created in the test.
252232
await()
253233
.untilAsserted(
254234
() -> {
@@ -257,16 +237,10 @@ void configures() throws Exception {
257237
assertThat(metricRequest.getResourceMetricsList())
258238
.satisfiesExactly(
259239
resourceMetrics -> {
260-
assertThat(resourceMetrics.getResource().getAttributesList())
261-
.contains(
262-
KeyValue.newBuilder()
263-
.setKey("service.name")
264-
.setValue(AnyValue.newBuilder().setStringValue("test").build())
265-
.build(),
266-
KeyValue.newBuilder()
267-
.setKey("cat")
268-
.setValue(AnyValue.newBuilder().setStringValue("meow").build())
269-
.build());
240+
List<KeyValue> metricResourceAttributes =
241+
resourceMetrics.getResource().getAttributesList();
242+
assertHasKeyValue(metricResourceAttributes, "service.name", "test");
243+
assertHasKeyValue(metricResourceAttributes, "cat", "meow");
270244
assertThat(resourceMetrics.getScopeMetricsList())
271245
.anySatisfy(
272246
scopeMetrics -> {
@@ -277,18 +251,10 @@ void configures() throws Exception {
277251
// SPI was loaded
278252
assertThat(metric.getName()).isEqualTo("my-metric");
279253
// TestMeterProviderConfigurer configures a view that
280-
// only passes on attribute
281-
// named allowed
254+
// only passes an attribute named "allowed"
282255
// configured-test
283-
assertThat(getFirstDataPointLabels(metric))
284-
.contains(
285-
KeyValue.newBuilder()
286-
.setKey("allowed")
287-
.setValue(
288-
AnyValue.newBuilder()
289-
.setStringValue("bear")
290-
.build())
291-
.build());
256+
assertHasKeyValue(
257+
getFirstDataPointLabels(metric), "allowed", "bear");
292258
});
293259
})
294260
// This verifies that AutoConfigureListener was invoked and the OTLP
@@ -312,21 +278,20 @@ void configures() throws Exception {
312278

313279
await().untilAsserted(() -> assertThat(otlpLogsRequests).hasSize(1));
314280
ExportLogsServiceRequest logRequest = otlpLogsRequests.take();
315-
assertThat(logRequest.getResourceLogs(0).getResource().getAttributesList())
316-
.contains(
317-
KeyValue.newBuilder()
318-
.setKey("service.name")
319-
.setValue(AnyValue.newBuilder().setStringValue("test").build())
320-
.build(),
321-
KeyValue.newBuilder()
322-
.setKey("cat")
323-
.setValue(AnyValue.newBuilder().setStringValue("meow").build())
324-
.build());
281+
List<KeyValue> logResourceAttributes =
282+
logRequest.getResourceLogs(0).getResource().getAttributesList();
283+
assertHasKeyValue(logResourceAttributes, "service.name", "test");
284+
assertHasKeyValue(logResourceAttributes, "cat", "meow");
325285

326286
assertThat(logRequest.getResourceLogs(0).getScopeLogs(0).getLogRecordsList())
287+
// LogRecordCustomizer customizes BatchLogProcessor to add an extra attribute on every log
288+
// record
289+
.allSatisfy(
290+
logRecord ->
291+
assertHasKeyValue(logRecord.getAttributesList(), "extra-key", "extra-value"))
327292
.satisfiesExactlyInAnyOrder(
328293
logRecord -> {
329-
// LogRecordExporterCustomizer filters logs not whose level is less than Severity.INFO
294+
// LogRecordCustomizer filters logs not whose level is less than Severity.INFO
330295
assertThat(logRecord.getBody().getStringValue()).isEqualTo("info log message");
331296
assertThat(logRecord.getSeverityNumberValue())
332297
.isEqualTo(Severity.INFO.getSeverityNumber());
@@ -340,16 +305,37 @@ void configures() throws Exception {
340305
.build());
341306
assertThat(logRecord.getSeverityNumber())
342307
.isEqualTo(SeverityNumber.SEVERITY_NUMBER_INFO);
343-
assertThat(logRecord.getAttributesList())
344-
.containsExactlyInAnyOrder(
345-
KeyValue.newBuilder()
346-
.setKey("event.name")
347-
.setValue(
348-
AnyValue.newBuilder().setStringValue("namespace.test-name").build())
349-
.build());
308+
assertHasKeyValue(logRecord.getAttributesList(), "event.name", "namespace.test-name");
350309
});
351310
}
352311

312+
private static void assertHasKeyValue(List<KeyValue> keyValues, String key, boolean value) {
313+
assertThat(keyValues)
314+
.contains(
315+
KeyValue.newBuilder()
316+
.setKey(key)
317+
.setValue(AnyValue.newBuilder().setBoolValue(value))
318+
.build());
319+
}
320+
321+
private static void assertHasKeyValue(List<KeyValue> keyValues, String key, long value) {
322+
assertThat(keyValues)
323+
.contains(
324+
KeyValue.newBuilder()
325+
.setKey(key)
326+
.setValue(AnyValue.newBuilder().setIntValue(value))
327+
.build());
328+
}
329+
330+
private static void assertHasKeyValue(List<KeyValue> keyValues, String key, String value) {
331+
assertThat(keyValues)
332+
.contains(
333+
KeyValue.newBuilder()
334+
.setKey(key)
335+
.setValue(AnyValue.newBuilder().setStringValue(value))
336+
.build());
337+
}
338+
353339
private static List<KeyValue> getFirstDataPointLabels(Metric metric) {
354340
switch (metric.getDataCase()) {
355341
case GAUGE:

0 commit comments

Comments
 (0)