Suppress instrumentation based on suppress Context key (#9739)

This commit is contained in:
César 2023-11-17 23:55:46 +01:00 committed by GitHub
parent c5cb94893b
commit 683c311de9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 1 deletions

View File

@ -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"))

View File

@ -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() {

View File

@ -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;
}
}
}
}

View File

@ -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));
}
}