From 581690ecaca5b92979f0ff559a083a63b4b98590 Mon Sep 17 00:00:00 2001 From: Chung Nguyen Date: Mon, 19 Aug 2024 20:57:08 +0200 Subject: [PATCH] supress zipkin exporters instrumentations (#6552) --- .../exporter/zipkin/ZipkinSpanExporter.java | 24 +++++--- .../zipkin/ZipkinSpanExporterTest.java | 58 +++++++++++++++++++ 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java index c92f70db3f5..a76d3177fd4 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.zipkin; +import io.opentelemetry.api.internal.InstrumentationUtil; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.ExporterMetrics; import io.opentelemetry.sdk.common.CompletableResultCode; @@ -75,15 +76,20 @@ public CompletableResultCode export(Collection spanDataList) { encodedSpans.add(encoder.encode(zipkinSpan)); } - try { - sender.send(encodedSpans); - exporterMetrics.addSuccess(numItems); - return CompletableResultCode.ofSuccess(); - } catch (IOException | RuntimeException t) { - exporterMetrics.addFailed(numItems); - logger.log(Level.WARNING, "Failed to export spans", t); - return CompletableResultCode.ofFailure(); - } + CompletableResultCode resultCode = new CompletableResultCode(); + InstrumentationUtil.suppressInstrumentation( + () -> { + try { + sender.send(encodedSpans); + exporterMetrics.addSuccess(numItems); + resultCode.succeed(); + } catch (IOException | RuntimeException e) { + exporterMetrics.addFailed(numItems); + logger.log(Level.WARNING, "Failed to export spans", e); + resultCode.fail(); + } + }); + return resultCode; } @Override diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java index 673855d4a8c..2c70691744c 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java @@ -9,12 +9,15 @@ import static io.opentelemetry.exporter.zipkin.ZipkinTestUtil.zipkinSpanBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.api.internal.InstrumentationUtil; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.context.Context; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.testing.trace.TestSpanData; @@ -22,7 +25,9 @@ import java.net.InetAddress; import java.time.Duration; import java.util.Collections; +import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; @@ -244,4 +249,57 @@ void stringRepresentation() { "ZipkinSpanExporter{endpoint=http://zipkin:9411/api/v2/spans, compressionEnabled=false, readTimeoutMillis=15000}"); } } + + @Test + void suppressInstrumentation() { + TestSpanData testSpanData = spanBuilder().build(); + + SuppressCatchingSender suppressCatchingSender = new SuppressCatchingSender(Encoding.JSON); + ZipkinSpanExporter zipkinSpanExporter = + new ZipkinSpanExporter( + new ZipkinSpanExporterBuilder(), + mockEncoder, + suppressCatchingSender, + MeterProvider::noop, + mockTransformer); + + byte[] someBytes = new byte[0]; + Span zipkinSpan = + zipkinSpanBuilder(Span.Kind.SERVER, localIp) + .putTag(OtelToZipkinSpanTransformer.OTEL_STATUS_CODE, "OK") + .build(); + when(mockTransformer.generateSpan(testSpanData)).thenReturn(zipkinSpan); + when(mockEncoder.encode(zipkinSpan)).thenReturn(someBytes); + + zipkinSpanExporter.export(Collections.singleton(testSpanData)); + + // Instrumentation should be suppressed on send, to avoid incidental spans related to span + // export. + assertTrue(suppressCatchingSender.sent.get()); + assertTrue(suppressCatchingSender.suppressed.get()); + } + + static class SuppressCatchingSender extends BytesMessageSender.Base { + + final AtomicBoolean sent = new AtomicBoolean(); + final AtomicBoolean suppressed = new AtomicBoolean(); + + protected SuppressCatchingSender(Encoding encoding) { + super(encoding); + } + + @Override + public int messageMaxBytes() { + return 1024; + } + + @Override + public void send(List list) throws IOException { + sent.set(true); + suppressed.set(InstrumentationUtil.shouldSuppressInstrumentation(Context.current())); + } + + @Override + public void close() throws IOException {} + } }