Fix code with suggestions from Tyler regarding previous commit.
no longer includes the command argument if the redis command being called is AUTH since it contains sensitive information.
This commit is contained in:
parent
ae1d9d7c52
commit
989a259ec2
|
@ -1,10 +1,37 @@
|
|||
apply from: "${rootDir}/gradle/java.gradle"
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
sourceSets {
|
||||
main_java8 {
|
||||
java.srcDirs "${project.projectDir}/src/main/java8"
|
||||
}
|
||||
}
|
||||
|
||||
compileMain_java8Java {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
|
||||
apply plugin: 'org.unbroken-dome.test-sets'
|
||||
|
||||
testSets {
|
||||
latestDepTest {
|
||||
dirName = 'test'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly group: 'io.lettuce', name: 'lettuce-core', version: '5.0.4.RELEASE'
|
||||
main_java8CompileOnly group: 'io.lettuce', name: 'lettuce-core', version: '5.0.0.RELEASE'
|
||||
|
||||
main_java8Compile project(':dd-java-agent:agent-tooling')
|
||||
|
||||
main_java8Compile deps.bytebuddy
|
||||
main_java8Compile deps.opentracing
|
||||
|
||||
compileOnly sourceSets.main_java8.compileClasspath
|
||||
|
||||
compile sourceSets.main_java8.output
|
||||
|
||||
compileOnly group: 'io.lettuce', name: 'lettuce-core', version: '5.0.0.RELEASE'
|
||||
|
||||
compile project(':dd-java-agent:agent-tooling')
|
||||
|
||||
|
@ -16,5 +43,15 @@ dependencies {
|
|||
testCompile project(':dd-java-agent:testing')
|
||||
|
||||
testCompile group: 'com.github.kstyrc', name: 'embedded-redis', version: '0.6'
|
||||
testCompile group: 'io.lettuce', name: 'lettuce-core', version: '5.0.4.RELEASE'
|
||||
testCompile group: 'io.lettuce', name: 'lettuce-core', version: '5.0.0.RELEASE'
|
||||
}
|
||||
|
||||
configurations.latestDepTestCompile {
|
||||
resolutionStrategy {
|
||||
force group: 'io.lettuce', name: 'lettuce-core', version: '+'
|
||||
}
|
||||
}
|
||||
|
||||
testJava8Only += '**/LettuceAsyncClientTest.class'
|
||||
testJava8Only += '**/LettuceSyncClientTest.class'
|
||||
|
||||
|
|
|
@ -7,27 +7,17 @@ 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.api.DDTags;
|
||||
import io.lettuce.core.protocol.AsyncCommand;
|
||||
import io.lettuce.core.protocol.RedisCommand;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class RedisAsyncCommandsInstrumentation extends Instrumenter.Configurable {
|
||||
|
||||
private static final HelperInjector REDIS_ASYNC_HELPERS =
|
||||
new HelperInjector(RedisAsyncCommandsInstrumentation.class.getPackage().getName() + ".RedisAsyncBiFunction");
|
||||
private static final String SERVICE_NAME = "redis";
|
||||
private static final String COMPONENT_NAME = SERVICE_NAME + "-client";
|
||||
new HelperInjector(
|
||||
RedisAsyncCommandsInstrumentation.class.getPackage().getName() + ".RedisAsyncBiFunction");
|
||||
|
||||
public RedisAsyncCommandsInstrumentation() {
|
||||
super(SERVICE_NAME);
|
||||
super("redis");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,56 +40,4 @@ public class RedisAsyncCommandsInstrumentation extends Instrumenter.Configurable
|
|||
RedisAsyncCommandsAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
}
|
||||
|
||||
public static class RedisAsyncCommandsAdvice {
|
||||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static Scope startSpan(@Advice.Argument(0) final RedisCommand command) {
|
||||
final Scope scope = GlobalTracer.get().buildSpan(SERVICE_NAME + ".query").startActive(false);
|
||||
|
||||
final Span span = scope.span();
|
||||
Tags.DB_TYPE.set(span, SERVICE_NAME);
|
||||
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
|
||||
Tags.COMPONENT.set(span, COMPONENT_NAME);
|
||||
|
||||
String commandName = "Unknown Redis Command";
|
||||
String commandArgs = null;
|
||||
if (command != null) {
|
||||
// get the redis command name (i.e. GET, SET, HMSET, etc)
|
||||
if (command.getType() != null) {
|
||||
commandName = command.getType().name();
|
||||
}
|
||||
// get the arguments passed into the redis command
|
||||
if (command.getArgs() != null) {
|
||||
commandArgs = command.getArgs().toCommandString();
|
||||
}
|
||||
}
|
||||
|
||||
span.setTag(DDTags.RESOURCE_NAME, commandName);
|
||||
span.setTag("db.redis.command.args", commandArgs);
|
||||
span.setTag(DDTags.SERVICE_NAME, SERVICE_NAME);
|
||||
span.setTag(DDTags.SPAN_TYPE, SERVICE_NAME);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter final Scope scope,
|
||||
@Advice.Thrown final Throwable throwable,
|
||||
@Advice.Return(readOnly = false) final AsyncCommand<?, ?, ?> asyncCommand) {
|
||||
|
||||
if (throwable != null) {
|
||||
final Span span = scope.span();
|
||||
Tags.ERROR.set(span, true);
|
||||
span.log(Collections.singletonMap("error.object", throwable));
|
||||
scope.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// close spans on error or normal completion
|
||||
asyncCommand.handleAsync(new RedisAsyncBiFunction<>(scope.span()));
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,30 +7,17 @@ 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.api.DDTags;
|
||||
import io.lettuce.core.*;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class RedisClientInstrumentation extends Instrumenter.Configurable {
|
||||
|
||||
private static final HelperInjector REDIS_ASYNC_HELPERS =
|
||||
new HelperInjector(RedisAsyncCommandsInstrumentation.class.getPackage().getName() + ".RedisAsyncBiFunction");
|
||||
|
||||
public static final String SERVICE_NAME = "redis";
|
||||
public static final String COMPONENT_NAME = SERVICE_NAME + "-client";
|
||||
public static final String RESOURCE_NAME_PREFIX = "CONNECT:";
|
||||
public static final String REDIS_URL_TAG_NAME = "db.redis.url";
|
||||
public static final String REDIS_DB_INDEX_TAG_NAME = "db.redis.dbIndex";
|
||||
new HelperInjector(
|
||||
RedisAsyncCommandsInstrumentation.class.getPackage().getName() + ".RedisAsyncBiFunction");
|
||||
|
||||
public RedisClientInstrumentation() {
|
||||
super(SERVICE_NAME);
|
||||
super("redis");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,9 +28,7 @@ public final class RedisClientInstrumentation extends Instrumenter.Configurable
|
|||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("io.lettuce.core.RedisClient")
|
||||
.and(hasSuperType(named("io.lettuce.core.AbstractRedisClient"))))
|
||||
.type(named("io.lettuce.core.RedisClient"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(REDIS_ASYNC_HELPERS)
|
||||
.transform(
|
||||
|
@ -58,45 +43,4 @@ public final class RedisClientInstrumentation extends Instrumenter.Configurable
|
|||
ConnectionFutureAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
}
|
||||
|
||||
public static class ConnectionFutureAdvice {
|
||||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static Scope startSpan(@Advice.Argument(1) final RedisURI redisURI) {
|
||||
final Scope scope = GlobalTracer.get().buildSpan(SERVICE_NAME + ".query").startActive(false);
|
||||
|
||||
final Span span = scope.span();
|
||||
Tags.DB_TYPE.set(span, SERVICE_NAME);
|
||||
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
|
||||
Tags.COMPONENT.set(span, COMPONENT_NAME);
|
||||
|
||||
final String url =
|
||||
redisURI.getHost() + ":" + redisURI.getPort() + "/" + redisURI.getDatabase();
|
||||
span.setTag(REDIS_URL_TAG_NAME, url);
|
||||
span.setTag(REDIS_DB_INDEX_TAG_NAME, redisURI.getDatabase());
|
||||
span.setTag(DDTags.RESOURCE_NAME, RESOURCE_NAME_PREFIX + url);
|
||||
span.setTag(DDTags.SERVICE_NAME, SERVICE_NAME);
|
||||
span.setTag(DDTags.SPAN_TYPE, SERVICE_NAME);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter final Scope scope,
|
||||
@Advice.Thrown final Throwable throwable,
|
||||
@Advice.Return(readOnly = false) final ConnectionFuture connectionFuture) {
|
||||
if (throwable != null) {
|
||||
final Span span = scope.span();
|
||||
Tags.ERROR.set(span, true);
|
||||
span.log(Collections.singletonMap("error.object", throwable));
|
||||
scope.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// close spans on error or normal completion
|
||||
connectionFuture.handleAsync(new RedisAsyncBiFunction<>(scope.span()));
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package datadog.trace.instrumentation.lettuce;
|
||||
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.lettuce.core.ConnectionFuture;
|
||||
import io.lettuce.core.RedisURI;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
||||
public class ConnectionFutureAdvice {
|
||||
|
||||
public static final String SERVICE_NAME = "redis";
|
||||
public static final String COMPONENT_NAME = SERVICE_NAME + "-client";
|
||||
public static final String REDIS_URL_TAG_NAME = "db.redis.url";
|
||||
public static final String REDIS_DB_INDEX_TAG_NAME = "db.redis.dbIndex";
|
||||
public static final String RESOURCE_NAME_PREFIX = "CONNECT:";
|
||||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static Scope startSpan(@Advice.Argument(1) final RedisURI redisURI) {
|
||||
final Scope scope = GlobalTracer.get().buildSpan("redis.query").startActive(false);
|
||||
|
||||
final Span span = scope.span();
|
||||
Tags.DB_TYPE.set(span, SERVICE_NAME);
|
||||
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
|
||||
Tags.COMPONENT.set(span, COMPONENT_NAME);
|
||||
|
||||
final int redisPort = redisURI.getPort();
|
||||
Tags.PEER_PORT.set(span, redisPort);
|
||||
final String redisHost = redisURI.getHost();
|
||||
Tags.PEER_HOSTNAME.set(span, redisHost);
|
||||
|
||||
final String url = redisHost + ":" + redisPort + "/" + redisURI.getDatabase();
|
||||
span.setTag(REDIS_URL_TAG_NAME, url);
|
||||
span.setTag(REDIS_DB_INDEX_TAG_NAME, redisURI.getDatabase());
|
||||
span.setTag(DDTags.RESOURCE_NAME, RESOURCE_NAME_PREFIX + url);
|
||||
span.setTag(DDTags.SERVICE_NAME, SERVICE_NAME);
|
||||
span.setTag(DDTags.SPAN_TYPE, SERVICE_NAME);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter final Scope scope,
|
||||
@Advice.Thrown final Throwable throwable,
|
||||
@Advice.Return final ConnectionFuture connectionFuture) {
|
||||
if (throwable != null) {
|
||||
final Span span = scope.span();
|
||||
Tags.ERROR.set(span, true);
|
||||
span.log(Collections.singletonMap("error.object", throwable));
|
||||
scope.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// close spans on error or normal completion
|
||||
connectionFuture.handleAsync(new RedisAsyncBiFunction<>(scope.span()));
|
||||
scope.close();
|
||||
}
|
||||
}
|
|
@ -6,12 +6,13 @@ import java.util.Collections;
|
|||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* Callback class to close the span on an error or a success in the RedisFuture returned by
|
||||
* the lettuce async API
|
||||
* Callback class to close the span on an error or a success in the RedisFuture returned by the
|
||||
* lettuce async API
|
||||
*
|
||||
* @param <T> the normal completion result
|
||||
* @param <U> the error
|
||||
* @param <R> the return type, should be null since nothing else should happen from tracing standpoint
|
||||
* after the span is closed
|
||||
* @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>
|
||||
implements BiFunction<T, Throwable, R> {
|
|
@ -0,0 +1,70 @@
|
|||
package datadog.trace.instrumentation.lettuce;
|
||||
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.lettuce.core.protocol.AsyncCommand;
|
||||
import io.lettuce.core.protocol.RedisCommand;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
||||
public class RedisAsyncCommandsAdvice {
|
||||
|
||||
private static final String SERVICE_NAME = "redis";
|
||||
private static final String COMPONENT_NAME = SERVICE_NAME + "-client";
|
||||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static Scope startSpan(@Advice.Argument(0) final RedisCommand command) {
|
||||
final Scope scope = GlobalTracer.get().buildSpan(SERVICE_NAME + ".query").startActive(false);
|
||||
|
||||
final Span span = scope.span();
|
||||
Tags.DB_TYPE.set(span, SERVICE_NAME);
|
||||
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
|
||||
Tags.COMPONENT.set(span, COMPONENT_NAME);
|
||||
|
||||
String commandName = "Redis Command";
|
||||
String commandArgs = null;
|
||||
if (command != null) {
|
||||
// get the arguments passed into the redis command
|
||||
if (command.getArgs() != null) {
|
||||
commandArgs = command.getArgs().toCommandString();
|
||||
}
|
||||
// get the redis command name (i.e. GET, SET, HMSET, etc)
|
||||
if (command.getType() != null) {
|
||||
commandName = command.getType().name();
|
||||
// if it is an AUTH command, then remove the extracted command arguments since it is the password
|
||||
if ("AUTH".equals(commandName)) {
|
||||
commandArgs = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span.setTag(DDTags.RESOURCE_NAME, commandName);
|
||||
span.setTag("db.command.args", commandArgs);
|
||||
span.setTag(DDTags.SERVICE_NAME, SERVICE_NAME);
|
||||
span.setTag(DDTags.SPAN_TYPE, SERVICE_NAME);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter final Scope scope,
|
||||
@Advice.Thrown final Throwable throwable,
|
||||
@Advice.Return final AsyncCommand<?, ?, ?> asyncCommand) {
|
||||
|
||||
if (throwable != null) {
|
||||
final Span span = scope.span();
|
||||
Tags.ERROR.set(span, true);
|
||||
span.log(Collections.singletonMap("error.object", throwable));
|
||||
scope.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// close spans on error or normal completion
|
||||
asyncCommand.handleAsync(new RedisAsyncBiFunction<>(scope.span()));
|
||||
scope.close();
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import datadog.trace.instrumentation.lettuce.RedisAsyncCommandsInstrumentation
|
||||
import datadog.trace.instrumentation.lettuce.RedisClientInstrumentation
|
||||
import datadog.trace.agent.test.TestUtils
|
||||
import io.lettuce.core.ConnectionFuture
|
||||
import io.lettuce.core.RedisClient
|
||||
import io.lettuce.core.RedisConnectionException
|
||||
import io.lettuce.core.RedisFuture
|
||||
import io.lettuce.core.RedisURI
|
||||
import io.lettuce.core.api.StatefulConnection
|
||||
|
@ -18,6 +18,9 @@ import java.util.function.BiFunction
|
|||
import java.util.function.Consumer
|
||||
import java.util.function.Function
|
||||
|
||||
import static datadog.trace.instrumentation.lettuce.ConnectionFutureAdvice.RESOURCE_NAME_PREFIX
|
||||
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
|
||||
|
||||
class LettuceAsyncClientTest extends AgentTestRunner {
|
||||
|
||||
static {
|
||||
|
@ -26,8 +29,8 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
|
||||
@Shared
|
||||
public static final String HOST = "127.0.0.1"
|
||||
public static final int PORT = 6399
|
||||
public static final int INCORRECT_PORT = 9999
|
||||
public static final int PORT = TestUtils.randomOpenPort()
|
||||
public static final int INCORRECT_PORT = TestUtils.randomOpenPort()
|
||||
public static final int DB_INDEX = 0
|
||||
@Shared
|
||||
public static final String DB_ADDR = HOST + ":" + PORT + "/" + DB_INDEX
|
||||
|
@ -69,10 +72,6 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
redisServer.stop()
|
||||
}
|
||||
|
||||
def setup() {
|
||||
TEST_WRITER.start()
|
||||
}
|
||||
|
||||
def "connect using get on ConnectionFuture"() {
|
||||
setup:
|
||||
RedisClient testConnectionClient = RedisClient.create(EMBEDDED_DB_URI)
|
||||
|
@ -83,26 +82,29 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
connection != null
|
||||
TEST_WRITER.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName RESOURCE_NAME_PREFIX + DB_ADDR
|
||||
errored false
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisClientInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisClientInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == RedisClientInstrumentation.RESOURCE_NAME_PREFIX + DB_ADDR
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags[RedisClientInstrumentation.REDIS_URL_TAG_NAME] == DB_ADDR
|
||||
tags[RedisClientInstrumentation.REDIS_DB_INDEX_TAG_NAME] == 0
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisClientInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisClientInstrumentation.SERVICE_NAME
|
||||
tags["component"] == RedisClientInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.redis.url" DB_ADDR
|
||||
"db.redis.dbIndex" 0
|
||||
"db.type" "redis"
|
||||
"peer.hostname" HOST
|
||||
"peer.port" PORT
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "connect exception inside the connection future"() {
|
||||
|
@ -121,26 +123,30 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
expect:
|
||||
TEST_WRITER.waitForTraces(1)
|
||||
connection == null
|
||||
TEST_WRITER.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName RESOURCE_NAME_PREFIX + DB_ADDR_NON_EXISTENT
|
||||
errored true
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisClientInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisClientInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == RedisClientInstrumentation.RESOURCE_NAME_PREFIX + DB_ADDR_NON_EXISTENT
|
||||
span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags[RedisClientInstrumentation.REDIS_URL_TAG_NAME] == DB_ADDR_NON_EXISTENT
|
||||
tags[RedisClientInstrumentation.REDIS_DB_INDEX_TAG_NAME] == 0
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisClientInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisClientInstrumentation.SERVICE_NAME
|
||||
tags["component"] == RedisClientInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.redis.url" DB_ADDR_NON_EXISTENT
|
||||
"db.redis.dbIndex" 0
|
||||
"db.type" "redis"
|
||||
errorTags(RedisConnectionException, "some error due to incorrect port number")
|
||||
"peer.hostname" HOST
|
||||
"peer.port" INCORRECT_PORT
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "set command using Future get with timeout"() {
|
||||
|
@ -151,24 +157,26 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
res == "OK"
|
||||
TEST_WRITER.size() == 1
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "SET"
|
||||
!span.context().getErrorFlag()
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "SET"
|
||||
errored false
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<TESTKEY> value<TESTVAL>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<TESTKEY> value<TESTVAL>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "get command chained with thenAccept"() {
|
||||
|
@ -188,27 +196,28 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
redisFuture.thenAccept(consumer)
|
||||
|
||||
then:
|
||||
conds.await()
|
||||
TEST_WRITER.waitForTraces(1)
|
||||
TEST_WRITER.size() == 1
|
||||
conds.await()
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "GET"
|
||||
errored false
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "GET"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<TESTKEY>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<TESTKEY>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// to make sure instrumentation's chained completion stages won't interfere with user's, while still
|
||||
|
@ -216,7 +225,7 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
def "get non existent key command with handleAsync and chained with thenApply"() {
|
||||
setup:
|
||||
def conds = new AsyncConditions()
|
||||
final String SUCCESS = "KEY MISSING"
|
||||
final String successStr = "KEY MISSING"
|
||||
BiFunction<String, Throwable, String> firstStage = new BiFunction<String, Throwable, String>() {
|
||||
@Override
|
||||
String apply(String res, Throwable throwable) {
|
||||
|
@ -224,14 +233,14 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
assert res == null
|
||||
assert throwable == null
|
||||
}
|
||||
return (res == null ? SUCCESS : res)
|
||||
return (res == null ? successStr : res)
|
||||
}
|
||||
}
|
||||
Function<String, Object> secondStage = new Function<String, Object>() {
|
||||
@Override
|
||||
Object apply(String input) {
|
||||
conds.evaluate{
|
||||
assert input == SUCCESS
|
||||
assert input == successStr
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
@ -242,27 +251,29 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
redisFuture.handleAsync(firstStage).thenApply(secondStage)
|
||||
|
||||
then:
|
||||
conds.await()
|
||||
TEST_WRITER.waitForTraces(1)
|
||||
TEST_WRITER.size() == 1
|
||||
conds.await()
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "GET"
|
||||
errored false
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "GET"
|
||||
!span.context().getErrorFlag()
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<NON_EXISTENT_KEY>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<NON_EXISTENT_KEY>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
}
|
||||
|
||||
def "command with no arguments using a biconsumer"() {
|
||||
|
@ -282,28 +293,27 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
redisFuture.whenCompleteAsync(biConsumer)
|
||||
|
||||
then:
|
||||
conds.await()
|
||||
TEST_WRITER.waitForTraces(1)
|
||||
TEST_WRITER.size() == 1
|
||||
conds.await()
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "RANDOMKEY"
|
||||
errored false
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "RANDOMKEY"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == null
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "hash set and then nest apply to hash getall"() {
|
||||
|
@ -315,8 +325,6 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
hmsetFuture.thenApplyAsync(new Function<String, Object>() {
|
||||
@Override
|
||||
Object apply(String setResult) {
|
||||
TEST_WRITER.waitForTraces(1)
|
||||
TEST_WRITER.start()
|
||||
conds.evaluate {
|
||||
assert setResult == "OK"
|
||||
}
|
||||
|
@ -343,25 +351,45 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
})
|
||||
|
||||
then:
|
||||
TEST_WRITER.waitForTraces(2)
|
||||
conds.await()
|
||||
TEST_WRITER.waitForTraces(1)
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
assertTraces(TEST_WRITER, 2) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "HMSET"
|
||||
errored false
|
||||
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "HGETALL"
|
||||
!span.context().getErrorFlag()
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<user> key<firstname> value<John> key<lastname> value<Doe> key<age> value<53>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "HGETALL"
|
||||
errored false
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<user>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<user>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import datadog.trace.instrumentation.lettuce.RedisAsyncCommandsInstrumentation
|
||||
import datadog.trace.instrumentation.lettuce.RedisClientInstrumentation
|
||||
import datadog.trace.agent.test.TestUtils
|
||||
import io.lettuce.core.RedisClient
|
||||
import io.lettuce.core.RedisConnectionException
|
||||
import io.lettuce.core.api.StatefulConnection
|
||||
|
@ -8,6 +7,9 @@ import io.lettuce.core.api.sync.RedisCommands
|
|||
import redis.embedded.RedisServer
|
||||
import spock.lang.Shared
|
||||
|
||||
import static datadog.trace.instrumentation.lettuce.ConnectionFutureAdvice.RESOURCE_NAME_PREFIX
|
||||
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
|
||||
|
||||
class LettuceSyncClientTest extends AgentTestRunner {
|
||||
|
||||
static {
|
||||
|
@ -16,12 +18,13 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
@Shared
|
||||
public static final String HOST = "127.0.0.1"
|
||||
public static final int PORT = 6399
|
||||
public static final int PORT = TestUtils.randomOpenPort()
|
||||
public static final int INCORRECT_PORT = TestUtils.randomOpenPort()
|
||||
public static final int DB_INDEX = 0
|
||||
@Shared
|
||||
public static final String DB_ADDR = HOST + ":" + PORT + "/" + DB_INDEX
|
||||
@Shared
|
||||
public static final String DB_ADDR_NON_EXISTENT = HOST + ":" + 9999 + "/" + DB_INDEX
|
||||
public static final String DB_ADDR_NON_EXISTENT = HOST + ":" + INCORRECT_PORT + "/" + DB_INDEX
|
||||
@Shared
|
||||
public static final String DB_URI_NON_EXISTENT = "redis://" + DB_ADDR_NON_EXISTENT
|
||||
public static final String EMBEDDED_DB_URI = "redis://" + DB_ADDR
|
||||
|
@ -48,7 +51,6 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
]
|
||||
|
||||
def setupSpec() {
|
||||
println "Using redis: $redisServer.args"
|
||||
redisServer.start()
|
||||
StatefulConnection connection = redisClient.connect()
|
||||
syncCommands = connection.sync()
|
||||
|
@ -58,10 +60,6 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
redisServer.stop()
|
||||
}
|
||||
|
||||
def setup() {
|
||||
TEST_WRITER.start()
|
||||
}
|
||||
|
||||
def "connect"() {
|
||||
setup:
|
||||
RedisClient testConnectionClient = RedisClient.create(EMBEDDED_DB_URI)
|
||||
|
@ -69,26 +67,29 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
TEST_WRITER.waitForTraces(1)
|
||||
|
||||
expect:
|
||||
TEST_WRITER.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName RESOURCE_NAME_PREFIX + DB_ADDR
|
||||
errored false
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisClientInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisClientInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == RedisClientInstrumentation.RESOURCE_NAME_PREFIX + DB_ADDR
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags[RedisClientInstrumentation.REDIS_URL_TAG_NAME] == DB_ADDR
|
||||
tags[RedisClientInstrumentation.REDIS_DB_INDEX_TAG_NAME] == 0
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisClientInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisClientInstrumentation.SERVICE_NAME
|
||||
tags["component"] == RedisClientInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.redis.url" DB_ADDR
|
||||
"db.redis.dbIndex" 0
|
||||
"db.type" "redis"
|
||||
"peer.hostname" HOST
|
||||
"peer.port" PORT
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "connect exception"() {
|
||||
|
@ -100,26 +101,30 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
TEST_WRITER.waitForTraces(1)
|
||||
|
||||
expect:
|
||||
TEST_WRITER.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName RESOURCE_NAME_PREFIX + DB_ADDR_NON_EXISTENT
|
||||
errored true
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisClientInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisClientInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == RedisClientInstrumentation.RESOURCE_NAME_PREFIX + DB_ADDR_NON_EXISTENT
|
||||
span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags[RedisClientInstrumentation.REDIS_URL_TAG_NAME] == DB_ADDR_NON_EXISTENT
|
||||
tags[RedisClientInstrumentation.REDIS_DB_INDEX_TAG_NAME] == 0
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisClientInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisClientInstrumentation.SERVICE_NAME
|
||||
tags["component"] == RedisClientInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.redis.url" DB_ADDR_NON_EXISTENT
|
||||
"db.redis.dbIndex" 0
|
||||
"db.type" "redis"
|
||||
errorTags(RedisConnectionException, "some error due to incorrect port number")
|
||||
"peer.hostname" HOST
|
||||
"peer.port" INCORRECT_PORT
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "set command"() {
|
||||
|
@ -129,26 +134,26 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
res == "OK"
|
||||
TEST_WRITER.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "SET"
|
||||
errored false
|
||||
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "SET"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<TESTKEY> value<TESTVAL>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<TESTKEY> value<TESTVAL>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "get command"() {
|
||||
|
@ -158,25 +163,26 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
res == "TESTVAL"
|
||||
TEST_WRITER.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "GET"
|
||||
errored false
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "GET"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<TESTKEY>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<TESTKEY>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "get non existent key command"() {
|
||||
|
@ -186,25 +192,26 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
res == null
|
||||
TEST_WRITER.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "GET"
|
||||
errored false
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "GET"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<NON_EXISTENT_KEY>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<NON_EXISTENT_KEY>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "command with no arguments"() {
|
||||
|
@ -214,26 +221,25 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
keyRetrieved == "TESTKEY"
|
||||
TEST_WRITER.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "RANDOMKEY"
|
||||
errored false
|
||||
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "RANDOMKEY"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == null
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "list command"() {
|
||||
|
@ -243,24 +249,26 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
res == 1
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "LPUSH"
|
||||
errored false
|
||||
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "LPUSH"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<TESTLIST> value<TESTLIST ELEMENT>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<TESTLIST> value<TESTLIST ELEMENT>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "hash set command"() {
|
||||
|
@ -270,24 +278,26 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
res == "OK"
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "HMSET"
|
||||
errored false
|
||||
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "HMSET"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<user> key<firstname> value<John> key<lastname> value<Doe> key<age> value<53>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<user> key<firstname> value<John> key<lastname> value<Doe> key<age> value<53>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "hash getall command"() {
|
||||
|
@ -297,23 +307,25 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
|
||||
expect:
|
||||
res == testHashMap
|
||||
def trace = TEST_WRITER.firstTrace()
|
||||
trace.size() == 1
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
serviceName "redis"
|
||||
operationName "redis.query"
|
||||
spanType "redis"
|
||||
resourceName "HGETALL"
|
||||
errored false
|
||||
|
||||
def span = trace[0]
|
||||
span.getServiceName() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getOperationName() == "redis.query"
|
||||
span.getType() == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
span.getResourceName() == "HGETALL"
|
||||
!span.context().getErrorFlag()
|
||||
|
||||
def tags = span.context().tags
|
||||
tags["span.kind"] == "client"
|
||||
tags["span.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.type"] == RedisAsyncCommandsInstrumentation.SERVICE_NAME
|
||||
tags["db.redis.command.args"] == "key<user>"
|
||||
tags["component"] == RedisAsyncCommandsInstrumentation.COMPONENT_NAME
|
||||
tags["thread.name"] != null
|
||||
tags["thread.id"] != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"component" "redis-client"
|
||||
"db.type" "redis"
|
||||
"db.command.args" "key<user>"
|
||||
"span.kind" "client"
|
||||
"span.type" "redis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue