Disable internal TaskScheduler spans in Spring Kafka instrumentation (#7553)

Resolves #7511

I used the same pattern we already have for suppressing the wrapping of
the Kafka consumer records lists.
This commit is contained in:
Mateusz Rzeszutek 2023-01-12 02:19:43 +01:00 committed by GitHub
parent 05e5316b84
commit 30de9ff266
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 3 deletions

View File

@ -16,12 +16,14 @@ dependencies {
annotationProcessor("com.google.auto.value:auto-value")
bootstrap(project(":instrumentation:kafka:kafka-clients:kafka-clients-0.11:bootstrap"))
bootstrap(project(":instrumentation:spring:spring-scheduling-3.1:bootstrap"))
implementation(project(":instrumentation:kafka:kafka-clients:kafka-clients-common:library"))
implementation(project(":instrumentation:spring:spring-kafka-2.7:library"))
library("org.springframework.kafka:spring-kafka:2.7.0")
testInstrumentation(project(":instrumentation:kafka:kafka-clients:kafka-clients-0.11:javaagent"))
testInstrumentation(project(":instrumentation:spring:spring-scheduling-3.1:javaagent"))
testImplementation(project(":instrumentation:spring:spring-kafka-2.7:testing"))

View File

@ -5,16 +5,18 @@
package io.opentelemetry.javaagent.instrumentation.spring.kafka;
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import io.opentelemetry.javaagent.bootstrap.kafka.KafkaClientsConsumerProcessTracing;
import io.opentelemetry.javaagent.bootstrap.spring.SpringSchedulingTaskTracing;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
public class SuppressingKafkaClientsInstrumentation implements TypeInstrumentation {
public class ListenerConsumerInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
@ -25,11 +27,14 @@ public class SuppressingKafkaClientsInstrumentation implements TypeInstrumentati
@Override
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(named("run"), this.getClass().getName() + "$RunLoopAdvice");
transformer.applyAdviceToMethod(
isConstructor(), this.getClass().getName() + "$ConstructorAdvice");
}
// this advice suppresses the CONSUMER spans created by the kafka-clients instrumentation
@SuppressWarnings("unused")
public static class RunLoopAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static boolean onEnter() {
return KafkaClientsConsumerProcessTracing.setEnabled(false);
@ -40,4 +45,19 @@ public class SuppressingKafkaClientsInstrumentation implements TypeInstrumentati
KafkaClientsConsumerProcessTracing.setEnabled(previousValue);
}
}
// this advice suppresses the spans generated by spring scheduling instrumentation
@SuppressWarnings("unused")
public static class ConstructorAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static boolean onEnter() {
return SpringSchedulingTaskTracing.setEnabled(false);
}
@Advice.OnMethodExit(suppress = Throwable.class)
public static void onExit(@Advice.Enter boolean previousValue) {
SpringSchedulingTaskTracing.setEnabled(previousValue);
}
}
}

View File

@ -22,6 +22,6 @@ public class SpringKafkaInstrumentationModule extends InstrumentationModule {
public List<TypeInstrumentation> typeInstrumentations() {
return asList(
new AbstractMessageListenerContainerInstrumentation(),
new SuppressingKafkaClientsInstrumentation());
new ListenerConsumerInstrumentation());
}
}

View File

@ -0,0 +1,3 @@
plugins {
id("otel.javaagent-bootstrap")
}

View File

@ -0,0 +1,23 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.bootstrap.spring;
public final class SpringSchedulingTaskTracing {
private static final ThreadLocal<Boolean> wrappingEnabled = ThreadLocal.withInitial(() -> true);
private SpringSchedulingTaskTracing() {}
public static boolean setEnabled(boolean enabled) {
boolean previous = wrappingEnabled.get();
wrappingEnabled.set(enabled);
return previous;
}
public static boolean wrappingEnabled() {
return wrappingEnabled.get();
}
}

View File

@ -12,6 +12,8 @@ muzzle {
}
dependencies {
bootstrap(project(":instrumentation:spring:spring-scheduling-3.1:bootstrap"))
// 3.2.3 is the first version with which the tests will run. Lower versions require other
// classes and packages to be imported. Versions 3.1.0+ work with the instrumentation.
library("org.springframework:spring-context:3.1.0.RELEASE")

View File

@ -10,6 +10,7 @@ import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import io.opentelemetry.javaagent.bootstrap.spring.SpringSchedulingTaskTracing;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
@ -34,7 +35,9 @@ public class TaskSchedulerInstrumentation implements TypeInstrumentation {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onSchedule(@Advice.Argument(value = 0, readOnly = false) Runnable runnable) {
runnable = SpringSchedulingRunnableWrapper.wrapIfNeeded(runnable);
if (SpringSchedulingTaskTracing.wrappingEnabled()) {
runnable = SpringSchedulingRunnableWrapper.wrapIfNeeded(runnable);
}
}
}
}

View File

@ -445,6 +445,7 @@ hideFromDependabot(":instrumentation:spring:spring-kafka-2.7:library")
hideFromDependabot(":instrumentation:spring:spring-kafka-2.7:testing")
hideFromDependabot(":instrumentation:spring:spring-rabbit-1.0:javaagent")
hideFromDependabot(":instrumentation:spring:spring-rmi-4.0:javaagent")
hideFromDependabot(":instrumentation:spring:spring-scheduling-3.1:bootstrap")
hideFromDependabot(":instrumentation:spring:spring-scheduling-3.1:javaagent")
hideFromDependabot(":instrumentation:spring:spring-web:spring-web-3.1:javaagent")
hideFromDependabot(":instrumentation:spring:spring-web:spring-web-3.1:library")