use enumsets for keyword checking
MODIFY
dd-java-agent/instrumentation/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce/LettuceClientInstrumentation.java
dd-java-agent/instrumentation/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce/LettuceClientInstrumentation.java
@@ -28,7 +28,8 @@ public final class LettuceClientInstrumentation extends Instrumenter.Default {
return new String[] {
packageName + ".LettuceClientDecorator",
packageName + ".LettuceInstrumentationUtil",
- packageName + ".InstrumentationPoints"
+ packageName + ".InstrumentationPoints",
+ packageName + ".LettuceAsyncBiFunction"
};
}

MODIFY
dd-java-agent/instrumentation/lettuce-4.0/src/main/java8/datadog/trace/instrumentation/lettuce/InstrumentationPoints.java
dd-java-agent/instrumentation/lettuce-4.0/src/main/java8/datadog/trace/instrumentation/lettuce/InstrumentationPoints.java
@@ -3,23 +3,22 @@ package datadog.trace.instrumentation.lettuce;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan;
import static datadog.trace.instrumentation.lettuce.LettuceClientDecorator.DECORATE;
-import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.doFinishSpanEarly;
+import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.finishSpanEarly;
import com.lambdaworks.redis.RedisURI;
import com.lambdaworks.redis.protocol.AsyncCommand;
import com.lambdaworks.redis.protocol.RedisCommand;
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
-import net.bytebuddy.asm.Advice;
@SuppressWarnings("rawtypes")
-public class InstrumentationPoints {
+public final class InstrumentationPoints {
public static AgentScope onEnter(RedisCommand command) {
AgentSpan span = startSpan("redis.query");
DECORATE.afterStart(span);
DECORATE.onCommand(span, command);
- return activateSpan(span, doFinishSpanEarly(command));
+ return activateSpan(span, finishSpanEarly(command));
}
public static void onReturn(RedisCommand command,
@@ -31,7 +30,7 @@ public class InstrumentationPoints {
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.finish();
- } else if (!doFinishSpanEarly(command)) {
+ } else if (!finishSpanEarly(command)) {
asyncCommand.handleAsync(new LettuceAsyncBiFunction<>(span));
}
scope.close();

MODIFY
dd-java-agent/instrumentation/lettuce-4.0/src/main/java8/datadog/trace/instrumentation/lettuce/LettuceClientDecorator.java
dd-java-agent/instrumentation/lettuce-4.0/src/main/java8/datadog/trace/instrumentation/lettuce/LettuceClientDecorator.java
package datadog.trace.instrumentation.lettuce;
+import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.getCommandResourceName;
+
import com.lambdaworks.redis.RedisURI;
import com.lambdaworks.redis.protocol.RedisCommand;
import datadog.trace.api.DDSpanTypes;
@@ -52,7 +54,6 @@ public class LettuceClientDecorator extends DatabaseClientDecorator<RedisURI> {
if (connection != null) {
span.setTag(Tags.PEER_HOSTNAME, connection.getHost());
span.setTag(Tags.PEER_PORT, connection.getPort());
-
span.setTag("db.redis.dbIndex", connection.getDatabase());
span.setTag(
DDTags.RESOURCE_NAME,
@@ -68,9 +69,8 @@ public class LettuceClientDecorator extends DatabaseClientDecorator<RedisURI> {
@SuppressWarnings("rawtypes")
public AgentSpan onCommand(final AgentSpan span, final RedisCommand command) {
- String commandName = LettuceInstrumentationUtil.getCommandName(command);
- span.setTag(
- DDTags.RESOURCE_NAME, LettuceInstrumentationUtil.getCommandResourceName(commandName));
+ span.setTag(DDTags.RESOURCE_NAME,
+ null == command ? "Redis Command" : getCommandResourceName(command.getType()));
return span;
}
}

MODIFY
dd-java-agent/instrumentation/lettuce-4.0/src/main/java8/datadog/trace/instrumentation/lettuce/LettuceInstrumentationUtil.java
dd-java-agent/instrumentation/lettuce-4.0/src/main/java8/datadog/trace/instrumentation/lettuce/LettuceInstrumentationUtil.java
package datadog.trace.instrumentation.lettuce;
+import static com.lambdaworks.redis.protocol.CommandKeyword.SEGFAULT;
+import static com.lambdaworks.redis.protocol.CommandType.CLIENT;
+import static com.lambdaworks.redis.protocol.CommandType.CLUSTER;
+import static com.lambdaworks.redis.protocol.CommandType.COMMAND;
+import static com.lambdaworks.redis.protocol.CommandType.CONFIG;
+import static com.lambdaworks.redis.protocol.CommandType.DEBUG;
+import static com.lambdaworks.redis.protocol.CommandType.SCRIPT;
+import static com.lambdaworks.redis.protocol.CommandType.SHUTDOWN;
+
+import com.lambdaworks.redis.protocol.CommandKeyword;
+import com.lambdaworks.redis.protocol.CommandType;
+import com.lambdaworks.redis.protocol.ProtocolKeyword;
import com.lambdaworks.redis.protocol.RedisCommand;
-import java.util.Arrays;
-import java.util.HashSet;
+
+import java.util.EnumSet;
import java.util.Set;
public class LettuceInstrumentationUtil {
public static final String AGENT_CRASHING_COMMAND_PREFIX = "COMMAND-NAME:";
- public static final Set<String> nonInstrumentingCommands =
- new HashSet<>(Arrays.asList("SHUTDOWN", "DEBUG", "OOM", "SEGFAULT"));
+ public static final EnumSet<CommandType> NON_INSTRUMENTING_COMMANDS = EnumSet.of(SHUTDOWN, DEBUG);
- public static final Set<String> agentCrashingCommands =
- new HashSet<>(Arrays.asList("CLIENT", "CLUSTER", "COMMAND", "CONFIG", "DEBUG", "SCRIPT"));
+ public static final EnumSet<CommandKeyword> NON_INSTRUMENTING_KEYWORDS = EnumSet.of(SEGFAULT);
+
+ public static final Set<CommandType> AGENT_CRASHING_COMMANDS = EnumSet.of(CLIENT, CLUSTER, COMMAND, CONFIG, DEBUG, SCRIPT);
/**
* Determines whether a redis command should finish its relevant span early (as soon as tags are
@@ -23,9 +35,17 @@ public class LettuceInstrumentationUtil {
* @param command
* @return true if finish the span early (the command will not have a return value)
*/
- public static boolean doFinishSpanEarly(final RedisCommand command) {
- final String commandName = LettuceInstrumentationUtil.getCommandName(command);
- return nonInstrumentingCommands.contains(commandName);
+ public static boolean finishSpanEarly(final RedisCommand<?, ?, ?> command) {
+ ProtocolKeyword keyword = command.getType();
+ return isNonInstrumentingCommand(keyword) || isNonInstrumentingKeyword(keyword);
+ }
+
+ private static boolean isNonInstrumentingCommand(ProtocolKeyword keyword) {
+ return keyword instanceof CommandType && NON_INSTRUMENTING_COMMANDS.contains(keyword);
+ }
+
+ private static boolean isNonInstrumentingKeyword(ProtocolKeyword keyword) {
+ return keyword instanceof CommandKeyword && NON_INSTRUMENTING_KEYWORDS.contains(keyword);
}
// Workaround to keep trace agent from crashing
@@ -41,31 +61,14 @@ public class LettuceInstrumentationUtil {
* https://github.com/DataDog/datadog-trace-agent/blob/master/quantizer/redis.go#L18 has list of
* commands that will currently fail at the trace agent level.
*
- * @param actualCommandName the actual redis command
+ * @param keyword the actual redis command
* @return the redis command with a prefix if it is a command that will crash the trace agent,
* otherwise, the original command is returned.
*/
- public static String getCommandResourceName(final String actualCommandName) {
- if (agentCrashingCommands.contains(actualCommandName)) {
- return AGENT_CRASHING_COMMAND_PREFIX + actualCommandName;
- }
- return actualCommandName;
- }
-
- /**
- * Retrieves the actual redis command name from a RedisCommand object
- *
- * @param command the lettuce RedisCommand object
- * @return the redis command as a string
- */
- public static String getCommandName(final RedisCommand command) {
- String commandName = "Redis Command";
- if (command != null) {
- // get the redis command name (i.e. GET, SET, HMSET, etc)
- if (command.getType() != null) {
- commandName = command.getType().name().trim();
- }
+ public static String getCommandResourceName(ProtocolKeyword keyword) {
+ if (keyword instanceof CommandType && AGENT_CRASHING_COMMANDS.contains(keyword)) {
+ return AGENT_CRASHING_COMMAND_PREFIX + keyword.name();
}
- return commandName;
+ return keyword.name();
}
}

use enumsets for keyword checking