Explorar el Código

Suppress instrumentation based on suppress Context key (#9739)

César hace 1 año
padre
commit
683c311de9

+ 1 - 0
instrumentation-api/build.gradle.kts

@@ -20,6 +20,7 @@ dependencies {
 
   testImplementation(project(":testing-common"))
   testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
+  testImplementation("io.opentelemetry:opentelemetry-exporter-common")
   testImplementation("org.junit-pioneer:junit-pioneer")
 
   jmhImplementation(project(":instrumentation-api-semconv"))

+ 2 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java

@@ -354,7 +354,8 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
   }
 
   SpanSuppressor buildSpanSuppressor() {
-    return spanSuppressionStrategy.create(getSpanKeysFromAttributesExtractors());
+    return new SpanSuppressors.ByContextKey(
+        spanSuppressionStrategy.create(getSpanKeysFromAttributesExtractors()));
   }
 
   private Set<SpanKey> getSpanKeysFromAttributesExtractors() {

+ 46 - 0
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressors.java

@@ -10,6 +10,8 @@ import io.opentelemetry.api.trace.Span;
 import io.opentelemetry.api.trace.SpanKind;
 import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.internal.SpanKey;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.Set;
 
@@ -85,4 +87,48 @@ final class SpanSuppressors {
       return true;
     }
   }
+
+  static class ByContextKey implements SpanSuppressor {
+    private final SpanSuppressor delegate;
+    private final Method shouldSuppressInstrumentation;
+
+    ByContextKey(SpanSuppressor delegate) {
+      this.delegate = delegate;
+      Method shouldSuppressInstrumentation;
+      try {
+        Class<?> instrumentationUtil =
+            Class.forName("io.opentelemetry.exporter.internal.InstrumentationUtil");
+        shouldSuppressInstrumentation =
+            instrumentationUtil.getDeclaredMethod("shouldSuppressInstrumentation", Context.class);
+      } catch (ClassNotFoundException | NoSuchMethodException e) {
+        shouldSuppressInstrumentation = null;
+      }
+      this.shouldSuppressInstrumentation = shouldSuppressInstrumentation;
+    }
+
+    @Override
+    public Context storeInContext(Context context, SpanKind spanKind, Span span) {
+      return delegate.storeInContext(context, spanKind, span);
+    }
+
+    @Override
+    public boolean shouldSuppress(Context parentContext, SpanKind spanKind) {
+      if (suppressByContextKey(parentContext)) {
+        return true;
+      }
+      return delegate.shouldSuppress(parentContext, spanKind);
+    }
+
+    private boolean suppressByContextKey(Context context) {
+      if (shouldSuppressInstrumentation == null) {
+        return false;
+      }
+
+      try {
+        return (boolean) shouldSuppressInstrumentation.invoke(null, context);
+      } catch (IllegalAccessException | InvocationTargetException e) {
+        return false;
+      }
+    }
+  }
 }

+ 21 - 0
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java

@@ -16,6 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import io.opentelemetry.api.trace.Span;
 import io.opentelemetry.api.trace.SpanKind;
 import io.opentelemetry.context.Context;
+import io.opentelemetry.exporter.internal.InstrumentationUtil;
 import io.opentelemetry.instrumentation.api.internal.SpanKey;
 import java.util.HashSet;
 import java.util.Set;
@@ -157,4 +158,24 @@ class SpanSuppressionStrategyTest {
 
     assertFalse(suppressor.shouldSuppress(context, SpanKind.SERVER));
   }
+
+  @Test
+  void context_shouldSuppressWhenKeyIsAvailableAndTrue() {
+    InstrumentationUtil.suppressInstrumentation(
+        () -> {
+          SpanSuppressor suppressor =
+              new SpanSuppressors.ByContextKey(SpanSuppressionStrategy.NONE.create(emptySet()));
+
+          assertTrue(suppressor.shouldSuppress(Context.current(), SpanKind.CLIENT));
+        });
+  }
+
+  @Test
+  void context_shouldNotSuppressWhenKeyIsNotAvailable() {
+    Context context = Context.current();
+    SpanSuppressor suppressor =
+        new SpanSuppressors.ByContextKey(SpanSuppressionStrategy.NONE.create(emptySet()));
+
+    assertFalse(suppressor.shouldSuppress(context, SpanKind.CLIENT));
+  }
 }