add version scan and rename instrumentation classes
This commit is contained in:
parent
3d61d839c8
commit
b694ecdf79
|
@ -1,3 +1,15 @@
|
|||
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 {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
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(
|
|
@ -0,0 +1,67 @@
|
|||
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();
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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>)
|
|
@ -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;
|
|
@ -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) {
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue