add version scan and rename instrumentation classes
MODIFY
dd-java-agent/instrumentation/lettuce-5/lettuce-5.gradle
dd-java-agent/instrumentation/lettuce-5/lettuce-5.gradle
+apply plugin: 'version-scan'
+
+versionScan {
+ group = "io.lettuce"
+ module = "lettuce-core"
+ versions = "[5.0.0.RELEASE,)"
+ scanDependencies = true
+ verifyPresent = [
+ "io.lettuce.core.RedisClient": null,
+ ]
+}
+
apply from: "${rootDir}/gradle/java.gradle"
sourceSets {

RENAME
dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/RedisAsyncCommandsInstrumentation.java
dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceAsyncCommandsInstrumentation.java
package datadog.trace.instrumentation.lettuce;
+import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
import static net.bytebuddy.matcher.ElementMatchers.*;
import com.google.auto.service.AutoService;
@@ -10,16 +11,17 @@ import datadog.trace.agent.tooling.Instrumenter;
import net.bytebuddy.agent.builder.AgentBuilder;
@AutoService(Instrumenter.class)
-public class RedisAsyncCommandsInstrumentation extends Instrumenter.Configurable {
+public class LettuceAsyncCommandsInstrumentation extends Instrumenter.Configurable {
private static final HelperInjector REDIS_ASYNC_HELPERS =
new HelperInjector(
- RedisAsyncCommandsInstrumentation.class.getPackage().getName() + ".RedisAsyncBiFunction",
- RedisAsyncCommandsInstrumentation.class.getPackage().getName()
+ LettuceAsyncCommandsInstrumentation.class.getPackage().getName()
+ + ".LettuceAsyncBiFunction",
+ LettuceAsyncCommandsInstrumentation.class.getPackage().getName()
+ ".LettuceInstrumentationUtil");
- public RedisAsyncCommandsInstrumentation() {
- super("redis");
+ public LettuceAsyncCommandsInstrumentation() {
+ super("lettuce", "lettuce-5-async");
}
@Override
@@ -30,7 +32,9 @@ public class RedisAsyncCommandsInstrumentation extends Instrumenter.Configurable
@Override
protected AgentBuilder apply(AgentBuilder agentBuilder) {
return agentBuilder
- .type(named("io.lettuce.core.AbstractRedisAsyncCommands"))
+ .type(
+ named("io.lettuce.core.AbstractRedisAsyncCommands"),
+ classLoaderHasClasses("io.lettuce.core.RedisClient"))
.transform(REDIS_ASYNC_HELPERS)
.transform(DDTransformers.defaultTransformers())
.transform(
@@ -39,7 +43,7 @@ public class RedisAsyncCommandsInstrumentation extends Instrumenter.Configurable
isMethod()
.and(named("dispatch"))
.and(takesArgument(0, named("io.lettuce.core.protocol.RedisCommand"))),
- RedisAsyncCommandsAdvice.class.getName()))
+ LettuceAsyncCommandsAdvice.class.getName()))
.asDecorator();
}
}

RENAME
dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/RedisClientInstrumentation.java
dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceClientInstrumentation.java
package datadog.trace.instrumentation.lettuce;
+import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
import static net.bytebuddy.matcher.ElementMatchers.*;
import com.google.auto.service.AutoService;
@@ -10,14 +11,16 @@ import datadog.trace.agent.tooling.Instrumenter;
import net.bytebuddy.agent.builder.AgentBuilder;
@AutoService(Instrumenter.class)
-public final class RedisClientInstrumentation extends Instrumenter.Configurable {
+public final class LettuceClientInstrumentation extends Instrumenter.Configurable {
private static final HelperInjector REDIS_ASYNC_HELPERS =
new HelperInjector(
- RedisAsyncCommandsInstrumentation.class.getPackage().getName() + ".RedisAsyncBiFunction");
+ LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
+ + ".LettuceInstrumentationUtil",
+ LettuceClientInstrumentation.class.getPackage().getName() + ".LettuceAsyncBiFunction");
- public RedisClientInstrumentation() {
- super("redis");
+ public LettuceClientInstrumentation() {
+ super("lettuce");
}
@Override
@@ -28,7 +31,9 @@ public final class RedisClientInstrumentation extends Instrumenter.Configurable
@Override
public AgentBuilder apply(final AgentBuilder agentBuilder) {
return agentBuilder
- .type(named("io.lettuce.core.RedisClient"))
+ .type(
+ named("io.lettuce.core.RedisClient"),
+ classLoaderHasClasses("io.lettuce.core.RedisClient"))
.transform(DDTransformers.defaultTransformers())
.transform(REDIS_ASYNC_HELPERS)
.transform(

ADD
dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceReactiveCommandsInstrumentation.java
+package datadog.trace.instrumentation.lettuce;
+
+import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
+import static net.bytebuddy.matcher.ElementMatchers.*;
+
+import com.google.auto.service.AutoService;
+import datadog.trace.agent.tooling.DDAdvice;
+import datadog.trace.agent.tooling.DDTransformers;
+import datadog.trace.agent.tooling.HelperInjector;
+import datadog.trace.agent.tooling.Instrumenter;
+import datadog.trace.instrumentation.lettuce.rx.LettuceFluxCreationAdvice;
+import datadog.trace.instrumentation.lettuce.rx.LettuceMonoCreationAdvice;
+import net.bytebuddy.agent.builder.AgentBuilder;
+
+@AutoService(Instrumenter.class)
+public class LettuceReactiveCommandsInstrumentation extends Instrumenter.Configurable {
+
+ private static final HelperInjector REDIS_RX_HELPERS =
+ new HelperInjector(
+ LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
+ + ".LettuceInstrumentationUtil",
+ LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
+ + ".rx.LettuceMonoCreationAdvice",
+ LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
+ + ".rx.LettuceMonoDualConsumer",
+ LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
+ + ".rx.LettuceFluxCreationAdvice",
+ LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
+ + ".rx.LettuceFluxTerminationRunnable",
+ LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
+ + ".rx.LettuceFluxTerminationRunnable$FluxOnSubscribeConsumer");
+
+ public LettuceReactiveCommandsInstrumentation() {
+ super("lettuce", "lettuce-5-rx");
+ }
+
+ @Override
+ protected boolean defaultEnabled() {
+ return false;
+ }
+
+ @Override
+ protected AgentBuilder apply(AgentBuilder agentBuilder) {
+ return agentBuilder
+ .type(
+ named("io.lettuce.core.AbstractRedisReactiveCommands"),
+ classLoaderHasClasses("io.lettuce.core.RedisClient"))
+ .transform(REDIS_RX_HELPERS)
+ .transform(DDTransformers.defaultTransformers())
+ .transform(
+ DDAdvice.create()
+ .advice(
+ isMethod()
+ .and(named("createMono"))
+ .and(takesArgument(0, named("java.util.function.Supplier")))
+ .and(returns(named("reactor.core.publisher.Mono"))),
+ LettuceMonoCreationAdvice.class.getName())
+ .advice(
+ isMethod()
+ .and(nameStartsWith("create"))
+ .and(nameEndsWith("Flux"))
+ .and(takesArgument(0, named("java.util.function.Supplier")))
+ .and(returns(named(("reactor.core.publisher.Flux")))),
+ LettuceFluxCreationAdvice.class.getName()))
+ .asDecorator();
+ }
+}

DELETE
dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/RedisReactiveCommandsInstrumentation.java
-package datadog.trace.instrumentation.lettuce;
-
-import static net.bytebuddy.matcher.ElementMatchers.*;
-
-import com.google.auto.service.AutoService;
-import datadog.trace.agent.tooling.DDAdvice;
-import datadog.trace.agent.tooling.DDTransformers;
-import datadog.trace.agent.tooling.HelperInjector;
-import datadog.trace.agent.tooling.Instrumenter;
-import datadog.trace.instrumentation.lettuce.rx.FluxCreationAdvice;
-import datadog.trace.instrumentation.lettuce.rx.MonoCreationAdvice;
-import net.bytebuddy.agent.builder.AgentBuilder;
-
-@AutoService(Instrumenter.class)
-public class RedisReactiveCommandsInstrumentation extends Instrumenter.Configurable {
-
- private static final HelperInjector REDIS_ASYNC_HELPERS =
- new HelperInjector(
- RedisReactiveCommandsInstrumentation.class.getPackage().getName()
- + ".LettuceInstrumentationUtil",
- RedisReactiveCommandsInstrumentation.class.getPackage().getName()
- + ".rx.MonoCreationAdvice",
- RedisReactiveCommandsInstrumentation.class.getPackage().getName()
- + ".rx.MonoDualConsumer",
- RedisReactiveCommandsInstrumentation.class.getPackage().getName()
- + ".rx.FluxCreationAdvice",
- RedisReactiveCommandsInstrumentation.class.getPackage().getName()
- + ".rx.FluxTerminationCancellableRunnable",
- RedisReactiveCommandsInstrumentation.class.getPackage().getName()
- + ".rx.FluxTerminationCancellableRunnable$FluxOnSubscribeConsumer");
-
- public RedisReactiveCommandsInstrumentation() {
- super("redis");
- }
-
- @Override
- protected boolean defaultEnabled() {
- return false;
- }
-
- @Override
- protected AgentBuilder apply(AgentBuilder agentBuilder) {
- return agentBuilder
- .type(named("io.lettuce.core.AbstractRedisReactiveCommands"))
- .transform(REDIS_ASYNC_HELPERS)
- .transform(DDTransformers.defaultTransformers())
- .transform(
- DDAdvice.create()
- .advice(
- isMethod()
- .and(named("createMono"))
- .and(takesArgument(0, named("java.util.function.Supplier")))
- .and(returns(named("reactor.core.publisher.Mono"))),
- MonoCreationAdvice.class.getName())
- .advice(
- isMethod()
- .and(nameStartsWith("create"))
- .and(nameEndsWith("Flux"))
- .and(takesArgument(0, named("java.util.function.Supplier")))
- .and(returns(named(("reactor.core.publisher.Flux")))),
- FluxCreationAdvice.class.getName()))
- .asDecorator();
- }
-}

MODIFY
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/ConnectionFutureAdvice.java
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/ConnectionFutureAdvice.java
@@ -54,7 +54,7 @@ public class ConnectionFutureAdvice {
}
// close spans on error or normal completion
- connectionFuture.handleAsync(new RedisAsyncBiFunction<>(scope.span()));
+ connectionFuture.handleAsync(new LettuceAsyncBiFunction<>(scope.span()));
scope.close();
}
}

RENAME
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/RedisAsyncBiFunction.java
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/LettuceAsyncBiFunction.java
@@ -15,12 +15,12 @@ import java.util.function.BiFunction;
* @param <R> the return type, should be null since nothing else should happen from tracing
* standpoint after the span is closed
*/
-public class RedisAsyncBiFunction<T extends Object, U extends Throwable, R extends Object>
+public class LettuceAsyncBiFunction<T extends Object, U extends Throwable, R extends Object>
implements BiFunction<T, Throwable, R> {
private final Span span;
- public RedisAsyncBiFunction(Span span) {
+ public LettuceAsyncBiFunction(Span span) {
this.span = span;
}

RENAME
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/RedisAsyncCommandsAdvice.java
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/LettuceAsyncCommandsAdvice.java
@@ -11,7 +11,7 @@ import java.util.Collections;
import java.util.Map;
import net.bytebuddy.asm.Advice;
-public class RedisAsyncCommandsAdvice {
+public class LettuceAsyncCommandsAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static Scope startSpan(@Advice.Argument(0) final RedisCommand command) {
@@ -54,7 +54,7 @@ public class RedisAsyncCommandsAdvice {
}
// close spans on error or normal completion
- asyncCommand.handleAsync(new RedisAsyncBiFunction<>(scope.span()));
+ asyncCommand.handleAsync(new LettuceAsyncBiFunction<>(scope.span()));
scope.close();
}
}

RENAME
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/rx/FluxCreationAdvice.java
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/rx/LettuceFluxCreationAdvice.java
@@ -7,7 +7,7 @@ import java.util.function.Supplier;
import net.bytebuddy.asm.Advice;
import reactor.core.publisher.Flux;
-public class FluxCreationAdvice {
+public class LettuceFluxCreationAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static Map<String, String> extractCommand(
@@ -21,8 +21,8 @@ public class FluxCreationAdvice {
@Advice.Return(readOnly = false) Flux<?> publisher) {
boolean finishSpanOnClose = LettuceInstrumentationUtil.doFinishSpanEarly(commandMap);
- FluxTerminationCancellableRunnable handler =
- new FluxTerminationCancellableRunnable(commandMap, finishSpanOnClose);
+ LettuceFluxTerminationRunnable handler =
+ new LettuceFluxTerminationRunnable(commandMap, finishSpanOnClose);
publisher = publisher.doOnSubscribe(handler.getOnSubscribeConsumer());
// don't register extra callbacks to finish the spans if the command being instrumented is one of those that return
// Mono<Void> (In here a flux is created first and then converted to Mono<Void>)

RENAME
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/rx/FluxTerminationCancellableRunnable.java
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/rx/LettuceFluxTerminationRunnable.java
@@ -15,14 +15,13 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Signal;
import reactor.core.publisher.SignalType;
-public class FluxTerminationCancellableRunnable implements Consumer<Signal>, Runnable {
+public class LettuceFluxTerminationRunnable implements Consumer<Signal>, Runnable {
private Span span = null;
private int numResults = 0;
private FluxOnSubscribeConsumer onSubscribeConsumer = null;
- public FluxTerminationCancellableRunnable(
- Map<String, String> commandMap, boolean finishSpanOnClose) {
+ public LettuceFluxTerminationRunnable(Map<String, String> commandMap, boolean finishSpanOnClose) {
this.onSubscribeConsumer = new FluxOnSubscribeConsumer(this, commandMap, finishSpanOnClose);
}
@@ -44,7 +43,7 @@ public class FluxTerminationCancellableRunnable implements Consumer<Signal>, Run
} else {
LoggerFactory.getLogger(Flux.class)
.error(
- "Failed to finish this.span, FluxTerminationCancellableRunnable cannot find this.span because "
+ "Failed to finish this.span, LettuceFluxTerminationRunnable cannot find this.span because "
+ "it probably wasn't started.");
}
}
@@ -66,19 +65,19 @@ public class FluxTerminationCancellableRunnable implements Consumer<Signal>, Run
} else {
LoggerFactory.getLogger(Flux.class)
.error(
- "Failed to finish this.span to indicate cancellation, FluxTerminationCancellableRunnable cannot find this.span because "
+ "Failed to finish this.span to indicate cancellation, LettuceFluxTerminationRunnable cannot find this.span because "
+ "it probably wasn't started.");
}
}
public static class FluxOnSubscribeConsumer implements Consumer<Subscription> {
- private final FluxTerminationCancellableRunnable owner;
+ private final LettuceFluxTerminationRunnable owner;
private final Map<String, String> commandMap;
private final boolean finishSpanOnClose;
public FluxOnSubscribeConsumer(
- FluxTerminationCancellableRunnable owner,
+ LettuceFluxTerminationRunnable owner,
Map<String, String> commandMap,
boolean finishSpanOnClose) {
this.owner = owner;

RENAME
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/rx/MonoCreationAdvice.java
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/rx/LettuceMonoCreationAdvice.java
@@ -7,10 +7,7 @@ import java.util.function.Supplier;
import net.bytebuddy.asm.Advice;
import reactor.core.publisher.Mono;
-public class MonoCreationAdvice {
-
- public static final String MAP_KEY_CMD_NAME = "CMD_NAME";
- public static final String MAP_KEY_CMD_ARGS = "CMD_ARGS";
+public class LettuceMonoCreationAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static Map<String, String> extractCommand(
@@ -26,7 +23,7 @@ public class MonoCreationAdvice {
@Advice.Return(readOnly = false) Mono<?> publisher) {
boolean finishSpanOnClose = LettuceInstrumentationUtil.doFinishSpanEarly(commandMap);
- MonoDualConsumer mdc = new MonoDualConsumer(commandMap, finishSpanOnClose);
+ LettuceMonoDualConsumer mdc = new LettuceMonoDualConsumer(commandMap, finishSpanOnClose);
publisher = publisher.doOnSubscribe(mdc);
// register the call back to close the span only if necessary
if (!finishSpanOnClose) {

RENAME
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/rx/MonoDualConsumer.java
dd-java-agent/instrumentation/lettuce-5/src/main/java8/datadog/trace/instrumentation/lettuce/rx/LettuceMonoDualConsumer.java
@@ -13,14 +13,14 @@ import java.util.function.Consumer;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
-public class MonoDualConsumer<R, T, U extends Throwable>
+public class LettuceMonoDualConsumer<R, T, U extends Throwable>
implements Consumer<R>, BiConsumer<T, Throwable> {
private Span span = null;
private final Map<String, String> commandMap;
private final boolean finishSpanOnClose;
- public MonoDualConsumer(Map<String, String> commandMap, boolean finishSpanOnClose) {
+ public LettuceMonoDualConsumer(Map<String, String> commandMap, boolean finishSpanOnClose) {
this.commandMap = commandMap;
this.finishSpanOnClose = finishSpanOnClose;
}

MODIFY
dd-java-agent/instrumentation/lettuce-5/src/test/groovy/LettuceAsyncClientTest.groovy
dd-java-agent/instrumentation/lettuce-5/src/test/groovy/LettuceAsyncClientTest.groovy
@@ -27,7 +27,7 @@ import static datadog.trace.agent.test.ListWriterAssert.assertTraces
class LettuceAsyncClientTest extends AgentTestRunner {
static {
- System.setProperty("dd.integration.redis.enabled", "true")
+ System.setProperty("dd.integration.lettuce.enabled", "true")
}
@Shared
@@ -137,7 +137,7 @@ class LettuceAsyncClientTest extends AgentTestRunner {
"db.redis.url" DB_ADDR_NON_EXISTENT
"db.redis.dbIndex" 0
"db.type" "redis"
- errorTags CompletionException
+ errorTags CompletionException, String
"peer.hostname" HOST
"peer.port" INCORRECT_PORT
"span.kind" "client"

MODIFY
dd-java-agent/instrumentation/lettuce-5/src/test/groovy/LettuceReactiveClientTest.groovy
dd-java-agent/instrumentation/lettuce-5/src/test/groovy/LettuceReactiveClientTest.groovy
@@ -14,7 +14,7 @@ import static datadog.trace.agent.test.ListWriterAssert.assertTraces
class LettuceReactiveClientTest extends AgentTestRunner {
static {
- System.setProperty("dd.integration.redis.enabled", "true")
+ System.setProperty("dd.integration.lettuce.enabled", "true")
}
@Shared

MODIFY
dd-java-agent/instrumentation/lettuce-5/src/test/groovy/LettuceSyncClientTest.groovy
dd-java-agent/instrumentation/lettuce-5/src/test/groovy/LettuceSyncClientTest.groovy
@@ -15,7 +15,7 @@ import static datadog.trace.agent.test.ListWriterAssert.assertTraces
class LettuceSyncClientTest extends AgentTestRunner {
static {
- System.setProperty("dd.integration.redis.enabled", "true")
+ System.setProperty("dd.integration.lettuce.enabled", "true")
}
@Shared
@@ -117,7 +117,7 @@ class LettuceSyncClientTest extends AgentTestRunner {
"db.redis.url" DB_ADDR_NON_EXISTENT
"db.redis.dbIndex" 0
"db.type" "redis"
- errorTags CompletionException
+ errorTags CompletionException, String
"peer.hostname" HOST
"peer.port" INCORRECT_PORT
"span.kind" "client"

MODIFY
dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/TagsAssert.groovy
dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/TagsAssert.groovy
@@ -40,10 +40,6 @@ class TagsAssert {
if (message != null) {
methodMissing("error.msg", [message].toArray())
- } else {
- // don't make the message check mandatory, in case of exception messages that change on every run,
- // i.e. random port that is destined to fail every time
- assertedTags.add("error.msg")
}
}

add version scan and rename instrumentation classes