Lettuce 5.1 instrumentation should log normalised commands as db.statement (#1405)
This commit is contained in:
parent
a5475b23a4
commit
f077b23c9f
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.api.tracer.utils;
|
||||
|
||||
import io.opentelemetry.common.AttributeKey;
|
||||
import io.opentelemetry.instrumentation.api.config.Config;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import io.opentelemetry.trace.attributes.SemanticAttributes;
|
||||
|
@ -30,13 +31,15 @@ public final class NetPeerUtils {
|
|||
setNetPeer(span, remoteAddress, remoteConnection.getPort());
|
||||
} else {
|
||||
// Failed DNS lookup, the host string is the name.
|
||||
setNetPeer(span, remoteConnection.getHostString(), null, remoteConnection.getPort());
|
||||
setNetPeer(
|
||||
span::setAttribute, remoteConnection.getHostString(), null, remoteConnection.getPort());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setNetPeer(Span span, InetAddress remoteAddress, int port) {
|
||||
setNetPeer(span, remoteAddress.getHostName(), remoteAddress.getHostAddress(), port);
|
||||
setNetPeer(
|
||||
span::setAttribute, remoteAddress.getHostName(), remoteAddress.getHostAddress(), port);
|
||||
}
|
||||
|
||||
public static void setNetPeer(Span span, String nameOrIp, int port) {
|
||||
|
@ -45,16 +48,20 @@ public final class NetPeerUtils {
|
|||
setNetPeer(span, address);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// can't create address, try setting directly
|
||||
setNetPeer(span, nameOrIp, null, port);
|
||||
setNetPeer(span::setAttribute, nameOrIp, null, port);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setNetPeer(Span span, String peerName, String peerIp) {
|
||||
setNetPeer(span, peerName, peerIp, -1);
|
||||
setNetPeer(span::setAttribute, peerName, peerIp, -1);
|
||||
}
|
||||
|
||||
public static void setNetPeer(Span span, String peerName, String peerIp, int port) {
|
||||
setNetPeer(span::setAttribute, peerName, peerIp, port);
|
||||
}
|
||||
|
||||
public static void setNetPeer(
|
||||
SpanAttributeSetter span, String peerName, String peerIp, int port) {
|
||||
if (peerName != null && !peerName.equals(peerIp)) {
|
||||
span.setAttribute(SemanticAttributes.NET_PEER_NAME, peerName);
|
||||
}
|
||||
|
@ -81,4 +88,12 @@ public final class NetPeerUtils {
|
|||
|
||||
return ENDPOINT_PEER_SERVICE_MAPPING.get(endpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper interface allows setting attributes on both {@link Span} and {@link Span.Builder}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SpanAttributeSetter {
|
||||
<T> void setAttribute(AttributeKey<T> key, @Nullable T value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.lettuce.v5_1;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class LettuceArgSplitter {
|
||||
private static final Pattern KEY_PATTERN =
|
||||
Pattern.compile("((key|value)<(?<wrapped>[^>]+)>|(?<plain>[0-9A-Za-z=]+))(\\s+|$)");
|
||||
|
||||
// this method removes the key|value<...> wrappers around redis keys or values and splits the args
|
||||
// string
|
||||
public static List<String> splitArgs(@Nullable String args) {
|
||||
if (args == null || args.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> argsList = new ArrayList<>();
|
||||
Matcher m = KEY_PATTERN.matcher(args);
|
||||
while (m.find()) {
|
||||
String wrapped = m.group("wrapped");
|
||||
if (wrapped != null) {
|
||||
argsList.add(wrapped);
|
||||
} else {
|
||||
argsList.add(m.group("plain"));
|
||||
}
|
||||
}
|
||||
return argsList;
|
||||
}
|
||||
|
||||
private LettuceArgSplitter() {}
|
||||
}
|
|
@ -41,6 +41,13 @@ public class LettuceClientResourcesInstrumentation extends Instrumenter.Default
|
|||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
packageName + ".RedisCommandNormalizer",
|
||||
packageName + ".RedisCommandNormalizer$CommandNormalizer",
|
||||
packageName + ".RedisCommandNormalizer$CommandNormalizer$KeepAllArgs",
|
||||
packageName + ".RedisCommandNormalizer$CommandNormalizer$CommandAndNumArgs",
|
||||
packageName + ".RedisCommandNormalizer$CommandNormalizer$MultiKeyValue",
|
||||
packageName + ".RedisCommandNormalizer$CommandNormalizer$Eval",
|
||||
packageName + ".LettuceArgSplitter",
|
||||
packageName + ".OpenTelemetryTracing",
|
||||
packageName + ".OpenTelemetryTracing$OpenTelemetryTracerProvider",
|
||||
packageName + ".OpenTelemetryTracing$OpenTelemetryTraceContextProvider",
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.lettuce.v5_1;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.lettuce.v5_1.LettuceArgSplitter.splitArgs;
|
||||
|
||||
import io.grpc.Context;
|
||||
import io.lettuce.core.tracing.TraceContext;
|
||||
import io.lettuce.core.tracing.TraceContextProvider;
|
||||
|
@ -12,6 +14,8 @@ import io.lettuce.core.tracing.Tracer;
|
|||
import io.lettuce.core.tracing.TracerProvider;
|
||||
import io.lettuce.core.tracing.Tracing;
|
||||
import io.opentelemetry.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils;
|
||||
import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils.SpanAttributeSetter;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.jdbc.DbSystem;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import io.opentelemetry.trace.Span.Kind;
|
||||
|
@ -23,7 +27,7 @@ import java.time.Instant;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import reactor.util.annotation.Nullable;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public enum OpenTelemetryTracing implements Tracing {
|
||||
INSTANCE;
|
||||
|
@ -57,8 +61,8 @@ public enum OpenTelemetryTracing implements Tracing {
|
|||
if (socketAddress instanceof InetSocketAddress) {
|
||||
InetSocketAddress address = (InetSocketAddress) socketAddress;
|
||||
|
||||
return new OpenTelemetryEndpoint(
|
||||
address.getAddress().getHostAddress(), address.getPort(), address.getHostString());
|
||||
String ip = address.getAddress() == null ? null : address.getAddress().getHostAddress();
|
||||
return new OpenTelemetryEndpoint(ip, address.getPort(), address.getHostString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -96,18 +100,14 @@ public enum OpenTelemetryTracing implements Tracing {
|
|||
}
|
||||
|
||||
private static class OpenTelemetryEndpoint implements Endpoint {
|
||||
final String ip;
|
||||
@Nullable final String ip;
|
||||
final int port;
|
||||
@Nullable final String name;
|
||||
|
||||
OpenTelemetryEndpoint(String ip, int port, @Nullable String name) {
|
||||
OpenTelemetryEndpoint(@Nullable String ip, int port, @Nullable String name) {
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
if (!ip.equals(name)) {
|
||||
this.name = name;
|
||||
} else {
|
||||
this.name = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,9 +175,9 @@ public enum OpenTelemetryTracing implements Tracing {
|
|||
public synchronized Tracer.Span remoteEndpoint(Endpoint endpoint) {
|
||||
if (endpoint instanceof OpenTelemetryEndpoint) {
|
||||
if (span != null) {
|
||||
fillEndpoint(span, (OpenTelemetryEndpoint) endpoint);
|
||||
fillEndpoint(span::setAttribute, (OpenTelemetryEndpoint) endpoint);
|
||||
} else {
|
||||
fillEndpoint(spanBuilder, (OpenTelemetryEndpoint) endpoint);
|
||||
fillEndpoint(spanBuilder::setAttribute, (OpenTelemetryEndpoint) endpoint);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
@ -249,50 +249,20 @@ public enum OpenTelemetryTracing implements Tracing {
|
|||
public synchronized void finish() {
|
||||
if (span != null) {
|
||||
if (name != null) {
|
||||
String statement =
|
||||
(args != null && !args.isEmpty()) && !name.equals("AUTH") ? name + " " + args : name;
|
||||
String statement = RedisCommandNormalizer.normalize(name, splitArgs(args));
|
||||
span.setAttribute(SemanticAttributes.DB_STATEMENT, statement);
|
||||
}
|
||||
span.end();
|
||||
}
|
||||
}
|
||||
|
||||
private static void fillEndpoint(Span.Builder span, OpenTelemetryEndpoint endpoint) {
|
||||
private static void fillEndpoint(SpanAttributeSetter span, OpenTelemetryEndpoint endpoint) {
|
||||
span.setAttribute(SemanticAttributes.NET_TRANSPORT, "IP.TCP");
|
||||
span.setAttribute(SemanticAttributes.NET_PEER_IP, endpoint.ip);
|
||||
NetPeerUtils.setNetPeer(span, endpoint.name, endpoint.ip, endpoint.port);
|
||||
|
||||
StringBuilder redisUrl = new StringBuilder("redis://");
|
||||
|
||||
if (endpoint.name != null) {
|
||||
span.setAttribute(SemanticAttributes.NET_PEER_NAME, endpoint.name);
|
||||
redisUrl.append(endpoint.name);
|
||||
} else {
|
||||
redisUrl.append(endpoint.ip);
|
||||
}
|
||||
|
||||
if (endpoint.port != 0) {
|
||||
span.setAttribute(SemanticAttributes.NET_PEER_PORT, (long) endpoint.port);
|
||||
redisUrl.append(":").append(endpoint.port);
|
||||
}
|
||||
|
||||
span.setAttribute(SemanticAttributes.DB_CONNECTION_STRING, redisUrl.toString());
|
||||
}
|
||||
|
||||
private static void fillEndpoint(Span span, OpenTelemetryEndpoint endpoint) {
|
||||
span.setAttribute(SemanticAttributes.NET_TRANSPORT, "IP.TCP");
|
||||
span.setAttribute(SemanticAttributes.NET_PEER_IP, endpoint.ip);
|
||||
|
||||
StringBuilder redisUrl = new StringBuilder("redis://");
|
||||
|
||||
if (endpoint.name != null) {
|
||||
span.setAttribute(SemanticAttributes.NET_PEER_NAME, endpoint.name);
|
||||
redisUrl.append(endpoint.name);
|
||||
} else {
|
||||
redisUrl.append(endpoint.ip);
|
||||
}
|
||||
|
||||
if (endpoint.port != 0) {
|
||||
span.setAttribute(SemanticAttributes.NET_PEER_PORT, (long) endpoint.port);
|
||||
StringBuilder redisUrl =
|
||||
new StringBuilder("redis://").append(endpoint.name != null ? endpoint.name : endpoint.ip);
|
||||
if (endpoint.port > 0) {
|
||||
redisUrl.append(":").append(endpoint.port);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.lettuce.v5_1;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.lettuce.v5_1.RedisCommandNormalizer.CommandNormalizer.CommandAndNumArgs;
|
||||
import io.opentelemetry.javaagent.instrumentation.lettuce.v5_1.RedisCommandNormalizer.CommandNormalizer.Eval;
|
||||
import io.opentelemetry.javaagent.instrumentation.lettuce.v5_1.RedisCommandNormalizer.CommandNormalizer.KeepAllArgs;
|
||||
import io.opentelemetry.javaagent.instrumentation.lettuce.v5_1.RedisCommandNormalizer.CommandNormalizer.MultiKeyValue;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class is responsible for masking potentially sensitive data in Redis commands.
|
||||
*
|
||||
* <p>Examples:
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th>Raw command</th>
|
||||
* <th>Normalized command</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@code AUTH password}</td>
|
||||
* <td>{@code AUTH ?}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@code HMSET hash creditcard 1234567887654321 address asdf}</td>
|
||||
* <td>{@code HMSET hash creditcard ? address ?}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
public final class RedisCommandNormalizer {
|
||||
|
||||
private static final Map<String, CommandNormalizer> NORMALIZERS;
|
||||
private static final CommandNormalizer DEFAULT = new CommandAndNumArgs(0);
|
||||
|
||||
static {
|
||||
Map<String, CommandNormalizer> normalizers = new HashMap<>();
|
||||
|
||||
CommandNormalizer keepOneArg = new CommandAndNumArgs(1);
|
||||
CommandNormalizer keepTwoArgs = new CommandAndNumArgs(2);
|
||||
CommandNormalizer setMultiHashField = new MultiKeyValue(1);
|
||||
CommandNormalizer setMultiField = new MultiKeyValue(0);
|
||||
|
||||
// Cluster
|
||||
for (String command : asList("CLUSTER", "READONLY", "READWRITE")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Connection
|
||||
normalizers.put("AUTH", DEFAULT);
|
||||
// HELLO can contain AUTH data
|
||||
normalizers.put("HELLO", keepTwoArgs);
|
||||
for (String command : asList("CLIENT", "ECHO", "PING", "QUIT", "SELECT")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Geo
|
||||
for (String command :
|
||||
asList("GEOADD", "GEODIST", "GEOHASH", "GEOPOS", "GEORADIUS", "GEORADIUSBYMEMBER")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Hashes
|
||||
normalizers.put("HMSET", setMultiHashField);
|
||||
normalizers.put("HSET", setMultiHashField);
|
||||
normalizers.put("HSETNX", keepTwoArgs);
|
||||
for (String command :
|
||||
asList(
|
||||
"HDEL",
|
||||
"HEXISTS",
|
||||
"HGET",
|
||||
"HGETALL",
|
||||
"HINCRBY",
|
||||
"HINCRBYFLOAT",
|
||||
"HKEYS",
|
||||
"HLEN",
|
||||
"HMGET",
|
||||
"HSCAN",
|
||||
"HSTRLEN",
|
||||
"HVALS")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// HyperLogLog
|
||||
normalizers.put("PFADD", keepOneArg);
|
||||
for (String command : asList("PFCOUNT", "PFMERGE")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Keys
|
||||
// MIGRATE can contain AUTH data
|
||||
normalizers.put("MIGRATE", new CommandAndNumArgs(6));
|
||||
normalizers.put("RESTORE", keepTwoArgs);
|
||||
for (String command :
|
||||
asList(
|
||||
"DEL",
|
||||
"DUMP",
|
||||
"EXISTS",
|
||||
"EXPIRE",
|
||||
"EXPIREAT",
|
||||
"KEYS",
|
||||
"MOVE",
|
||||
"OBJECT",
|
||||
"PERSIST",
|
||||
"PEXPIRE",
|
||||
"PEXPIREAT",
|
||||
"PTTL",
|
||||
"RANDOMKEY",
|
||||
"RENAME",
|
||||
"RENAMENX",
|
||||
"SCAN",
|
||||
"SORT",
|
||||
"TOUCH",
|
||||
"TTL",
|
||||
"TYPE",
|
||||
"UNLINK",
|
||||
"WAIT")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Lists
|
||||
normalizers.put("LINSERT", keepTwoArgs);
|
||||
normalizers.put("LPOS", keepOneArg);
|
||||
normalizers.put("LPUSH", keepOneArg);
|
||||
normalizers.put("LPUSHX", keepOneArg);
|
||||
normalizers.put("LREM", keepOneArg);
|
||||
normalizers.put("LSET", keepOneArg);
|
||||
normalizers.put("RPUSH", keepOneArg);
|
||||
normalizers.put("RPUSHX", keepOneArg);
|
||||
for (String command :
|
||||
asList(
|
||||
"BLMOVE",
|
||||
"BLPOP",
|
||||
"BRPOP",
|
||||
"BRPOPLPUSH",
|
||||
"LINDEX",
|
||||
"LLEN",
|
||||
"LMOVE",
|
||||
"LPOP",
|
||||
"LRANGE",
|
||||
"LTRIM",
|
||||
"RPOP",
|
||||
"RPOPLPUSH")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Pub/Sub
|
||||
normalizers.put("PUBLISH", keepOneArg);
|
||||
for (String command :
|
||||
asList("PSUBSCRIBE", "PUBSUB", "PUNSUBSCRIBE", "SUBSCRIBE", "UNSUBSCRIBE")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Scripting
|
||||
normalizers.put("EVAL", Eval.INSTANCE);
|
||||
normalizers.put("EVALSHA", Eval.INSTANCE);
|
||||
normalizers.put("SCRIPT", KeepAllArgs.INSTANCE);
|
||||
|
||||
// Server
|
||||
// CONFIG SET can set any property, including the master password
|
||||
normalizers.put("CONFIG", keepTwoArgs);
|
||||
for (String command :
|
||||
asList(
|
||||
"ACL",
|
||||
"BGREWRITEAOF",
|
||||
"BGSAVE",
|
||||
"COMMAND",
|
||||
"DBSIZE",
|
||||
"DEBUG",
|
||||
"FLUSHALL",
|
||||
"FLUSHDB",
|
||||
"INFO",
|
||||
"LASTSAVE",
|
||||
"LATENCY",
|
||||
"LOLWUT",
|
||||
"MEMORY",
|
||||
"MODULE",
|
||||
"MONITOR",
|
||||
"PSYNC",
|
||||
"REPLICAOF",
|
||||
"ROLE",
|
||||
"SAVE",
|
||||
"SHUTDOWN",
|
||||
"SLAVEOF",
|
||||
"SLOWLOG",
|
||||
"SWAPDB",
|
||||
"SYNC",
|
||||
"TIME")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Sets
|
||||
normalizers.put("SADD", keepOneArg);
|
||||
normalizers.put("SISMEMBER", keepOneArg);
|
||||
normalizers.put("SMISMEMBER", keepOneArg);
|
||||
normalizers.put("SMOVE", keepTwoArgs);
|
||||
normalizers.put("SREM", keepOneArg);
|
||||
for (String command :
|
||||
asList(
|
||||
"SCARD",
|
||||
"SDIFF",
|
||||
"SDIFFSTORE",
|
||||
"SINTER",
|
||||
"SINTERSTORE",
|
||||
"SMEMBERS",
|
||||
"SPOP",
|
||||
"SRANDMEMBER",
|
||||
"SSCAN",
|
||||
"SUNION",
|
||||
"SUNIONSTORE")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Sorted Sets
|
||||
normalizers.put("ZADD", keepOneArg);
|
||||
normalizers.put("ZCOUNT", keepOneArg);
|
||||
normalizers.put("ZINCRBY", keepOneArg);
|
||||
normalizers.put("ZLEXCOUNT", keepOneArg);
|
||||
normalizers.put("ZMSCORE", keepOneArg);
|
||||
normalizers.put("ZRANGEBYLEX", keepOneArg);
|
||||
normalizers.put("ZRANGEBYSCORE", keepOneArg);
|
||||
normalizers.put("ZRANK", keepOneArg);
|
||||
normalizers.put("ZREM", keepOneArg);
|
||||
normalizers.put("ZREMRANGEBYLEX", keepOneArg);
|
||||
normalizers.put("ZREMRANGEBYSCORE", keepOneArg);
|
||||
normalizers.put("ZREVRANGEBYLEX", keepOneArg);
|
||||
normalizers.put("ZREVRANGEBYSCORE", keepOneArg);
|
||||
normalizers.put("ZREVRANK", keepOneArg);
|
||||
normalizers.put("ZSCORE", keepOneArg);
|
||||
for (String command :
|
||||
asList(
|
||||
"BZPOPMAX",
|
||||
"BZPOPMIN",
|
||||
"ZCARD",
|
||||
"ZINTER",
|
||||
"ZINTERSTORE",
|
||||
"ZPOPMAX",
|
||||
"ZPOPMIN",
|
||||
"ZRANGE",
|
||||
"ZREMRANGEBYRANK",
|
||||
"ZREVRANGE",
|
||||
"ZSCAN",
|
||||
"ZUNION",
|
||||
"ZUNIONSTORE")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Streams
|
||||
normalizers.put("XADD", new MultiKeyValue(2));
|
||||
for (String command :
|
||||
asList(
|
||||
"XACK",
|
||||
"XCLAIM",
|
||||
"XDEL",
|
||||
"XGROUP",
|
||||
"XINFO",
|
||||
"XLEN",
|
||||
"XPENDING",
|
||||
"XRANGE",
|
||||
"XREAD",
|
||||
"XREADGROUP",
|
||||
"XREVRANGE",
|
||||
"XTRIM")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Strings
|
||||
normalizers.put("APPEND", keepOneArg);
|
||||
normalizers.put("GETSET", keepOneArg);
|
||||
normalizers.put("MSET", setMultiField);
|
||||
normalizers.put("MSETNX", setMultiField);
|
||||
normalizers.put("PSETEX", keepTwoArgs);
|
||||
normalizers.put("SET", keepOneArg);
|
||||
normalizers.put("SETEX", keepTwoArgs);
|
||||
normalizers.put("SETNX", keepOneArg);
|
||||
normalizers.put("SETRANGE", keepOneArg);
|
||||
for (String command :
|
||||
asList(
|
||||
"BITCOUNT",
|
||||
"BITFIELD",
|
||||
"BITOP",
|
||||
"BITPOS",
|
||||
"DECR",
|
||||
"DECRBY",
|
||||
"GET",
|
||||
"GETBIT",
|
||||
"GETRANGE",
|
||||
"INCR",
|
||||
"INCRBY",
|
||||
"INCRBYFLOAT",
|
||||
"MGET",
|
||||
"SETBIT",
|
||||
"STRALGO",
|
||||
"STRLEN")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
// Transactions
|
||||
for (String command : asList("DISCARD", "EXEC", "MULTI", "UNWATCH", "WATCH")) {
|
||||
normalizers.put(command, KeepAllArgs.INSTANCE);
|
||||
}
|
||||
|
||||
NORMALIZERS = unmodifiableMap(normalizers);
|
||||
}
|
||||
|
||||
public static String normalize(String command, List<String> args) {
|
||||
return NORMALIZERS.getOrDefault(command.toUpperCase(), DEFAULT).normalize(command, args);
|
||||
}
|
||||
|
||||
public interface CommandNormalizer {
|
||||
String normalize(String command, List<String> args);
|
||||
|
||||
enum KeepAllArgs implements CommandNormalizer {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String normalize(String command, List<String> args) {
|
||||
StringBuilder normalised = new StringBuilder(command);
|
||||
for (String arg : args) {
|
||||
normalised.append(" ").append(arg);
|
||||
}
|
||||
return normalised.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// keeps only a chosen number of arguments
|
||||
// example for num=2: CMD arg1 arg2 ? ?
|
||||
class CommandAndNumArgs implements CommandNormalizer {
|
||||
private final int numOfArgsToKeep;
|
||||
|
||||
public CommandAndNumArgs(int numOfArgsToKeep) {
|
||||
this.numOfArgsToKeep = numOfArgsToKeep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalize(String command, List<String> args) {
|
||||
StringBuilder normalised = new StringBuilder(command);
|
||||
for (int i = 0; i < numOfArgsToKeep && i < args.size(); ++i) {
|
||||
normalised.append(" ").append(args.get(i));
|
||||
}
|
||||
for (int i = numOfArgsToKeep; i < args.size(); ++i) {
|
||||
normalised.append(" ?");
|
||||
}
|
||||
return normalised.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// keeps only chosen number of arguments and then every second one
|
||||
// example for num=2: CMD arg1 arg2 key1 ? key2 ?
|
||||
class MultiKeyValue implements CommandNormalizer {
|
||||
private final int numOfArgsBeforeKeyValue;
|
||||
|
||||
public MultiKeyValue(int numOfArgsBeforeKeyValue) {
|
||||
this.numOfArgsBeforeKeyValue = numOfArgsBeforeKeyValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalize(String command, List<String> args) {
|
||||
StringBuilder normalised = new StringBuilder(command);
|
||||
// append all "initial" arguments before key-value pairs start
|
||||
for (int i = 0; i < numOfArgsBeforeKeyValue && i < args.size(); ++i) {
|
||||
normalised.append(" ").append(args.get(i));
|
||||
}
|
||||
|
||||
// loop over keys only
|
||||
for (int i = numOfArgsBeforeKeyValue; i < args.size(); i += 2) {
|
||||
normalised.append(" ").append(args.get(i)).append(" ?");
|
||||
}
|
||||
return normalised.toString();
|
||||
}
|
||||
}
|
||||
|
||||
enum Eval implements CommandNormalizer {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String normalize(String command, List<String> args) {
|
||||
StringBuilder normalised = new StringBuilder(command);
|
||||
|
||||
// get the number of keys passed from the command itself (second arg)
|
||||
int numberOfKeys = 0;
|
||||
if (args.size() > 2) {
|
||||
try {
|
||||
numberOfKeys = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
// log the script, number of keys and all keys
|
||||
for (; i < (numberOfKeys + 2) && i < args.size(); ++i) {
|
||||
normalised.append(" ").append(args.get(i));
|
||||
}
|
||||
// mask the rest
|
||||
for (; i < args.size(); ++i) {
|
||||
normalised.append(" ?");
|
||||
}
|
||||
return normalised.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RedisCommandNormalizer() {}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.lettuce.v5_1
|
||||
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
class LettuceArgSplitterTest extends Specification {
|
||||
@Unroll
|
||||
def "should properly split #desc"() {
|
||||
expect:
|
||||
LettuceArgSplitter.splitArgs(args) == result
|
||||
|
||||
where:
|
||||
desc | args | result
|
||||
"a null value" | null | []
|
||||
"an empty value" | "" | []
|
||||
"a single key" | "key<key>" | ["key"]
|
||||
"a single value" | "value<value>" | ["value"]
|
||||
"a plain string" | "teststring" | ["teststring"]
|
||||
"an integer" | "42" | ["42"]
|
||||
"a base64 value" | "TeST123==" | ["TeST123=="]
|
||||
"a complex list of args" | "key<key> aSDFgh4321= 5 test value<val>" | ["key", "aSDFgh4321=", "5", "test", "val"]
|
||||
}
|
||||
}
|
|
@ -152,12 +152,12 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "SET key<TESTSETKEY> value<TESTSETVAL>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "SET TESTSETKEY ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -195,12 +195,12 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<TESTKEY>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET TESTKEY"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -252,12 +252,12 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<NON_EXISTENT_KEY>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET NON_EXISTENT_KEY"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -295,12 +295,12 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "RANDOMKEY"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "RANDOMKEY"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -356,12 +356,12 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "HMSET key<TESTHM> key<firstname> value<John> key<lastname> value<Doe> key<age> value<53>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "HMSET TESTHM firstname ? lastname ? age ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -377,12 +377,12 @@ class LettuceAsyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "HGETALL key<TESTHM>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "HGETALL TESTHM"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
|
|
@ -102,12 +102,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "SET key<TESTSETKEY> value<TESTSETVAL>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "SET TESTSETKEY ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -136,12 +136,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<TESTKEY>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET TESTKEY"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -178,12 +178,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<NON_EXISTENT_KEY>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET NON_EXISTENT_KEY"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -218,12 +218,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "RANDOMKEY"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "RANDOMKEY"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -248,12 +248,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "COMMAND"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "COMMAND"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -301,12 +301,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
errored false
|
||||
childOf span(0)
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "SET key<a> value<1>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "SET a ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -321,12 +321,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
errored false
|
||||
childOf span(0)
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<a>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET a"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -362,12 +362,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
errored false
|
||||
childOf span(0)
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "SET key<a> value<1>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "SET a ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -382,12 +382,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
errored false
|
||||
childOf span(0)
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<a>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET a"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -424,12 +424,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
errored false
|
||||
childOf span(0)
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "SET key<a> value<1>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "SET a ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -444,12 +444,12 @@ class LettuceReactiveClientTest extends AgentTestRunner {
|
|||
errored false
|
||||
childOf span(0)
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<a>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET a"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.lettuce.v5_1
|
||||
|
||||
import static io.opentelemetry.trace.Span.Kind.CLIENT
|
||||
|
||||
import io.lettuce.core.ClientOptions
|
||||
import io.lettuce.core.RedisClient
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
|
@ -13,8 +15,6 @@ import io.opentelemetry.trace.attributes.SemanticAttributes
|
|||
import redis.embedded.RedisServer
|
||||
import spock.lang.Shared
|
||||
|
||||
import static io.opentelemetry.trace.Span.Kind.CLIENT
|
||||
|
||||
class LettuceSyncClientAuthTest extends AgentTestRunner {
|
||||
public static final String HOST = "127.0.0.1"
|
||||
public static final int DB_INDEX = 0
|
||||
|
@ -74,12 +74,12 @@ class LettuceSyncClientAuthTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "AUTH"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "AUTH ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.lettuce.v5_1
|
||||
|
||||
import static io.opentelemetry.trace.Span.Kind.CLIENT
|
||||
import static java.nio.charset.StandardCharsets.UTF_8
|
||||
|
||||
import io.lettuce.core.ClientOptions
|
||||
import io.lettuce.core.RedisClient
|
||||
import io.lettuce.core.RedisConnectionException
|
||||
import io.lettuce.core.ScriptOutputType
|
||||
import io.lettuce.core.api.StatefulConnection
|
||||
import io.lettuce.core.api.sync.RedisCommands
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
|
@ -133,12 +135,12 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "SET key<TESTSETKEY> value<TESTSETVAL>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "SET TESTSETKEY ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -167,13 +169,13 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"net.peer.name" "localhost"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://localhost:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "SET key<TESTSETKEY> value<TESTSETVAL>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_NAME.key}" "localhost"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://localhost:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "SET TESTSETKEY ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -199,12 +201,12 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<TESTKEY>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET TESTKEY"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -230,12 +232,12 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "GET key<NON_EXISTENT_KEY>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "GET NON_EXISTENT_KEY"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -261,12 +263,12 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "RANDOMKEY"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "RANDOMKEY"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -292,12 +294,12 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "LPUSH key<TESTLIST> value<TESTLIST ELEMENT>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "LPUSH TESTLIST ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -323,12 +325,12 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "HMSET key<user> key<firstname> value<John> key<lastname> value<Doe> key<age> value<53>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "HMSET user firstname ? lastname ? age ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
@ -354,12 +356,83 @@ class LettuceSyncClientTest extends AgentTestRunner {
|
|||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key()}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key()}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key()}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key()}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key()}" "HGETALL key<TESTHM>"
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "HGETALL TESTHM"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
}
|
||||
event(1) {
|
||||
eventName "redis.encode.end"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "eval command"() {
|
||||
given:
|
||||
def script = "redis.call('lpush', KEYS[1], ARGV[1], ARGV[2]); return redis.call('llen', KEYS[1])"
|
||||
|
||||
when:
|
||||
def result = syncCommands.eval(script, ScriptOutputType.INTEGER, ["TESTLIST"] as String[], "abc", "def")
|
||||
|
||||
then:
|
||||
result == 2
|
||||
|
||||
def b64Script = Base64.encoder.encodeToString(script.getBytes(UTF_8))
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
name "EVAL"
|
||||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "EVAL $b64Script 1 TESTLIST ? ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
}
|
||||
event(1) {
|
||||
eventName "redis.encode.end"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "mset command"() {
|
||||
when:
|
||||
def res = syncCommands.mset([
|
||||
"key1": "value1",
|
||||
"key2": "value2"
|
||||
])
|
||||
|
||||
then:
|
||||
res == "OK"
|
||||
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
name "MSET"
|
||||
kind CLIENT
|
||||
errored false
|
||||
attributes {
|
||||
"${SemanticAttributes.NET_TRANSPORT.key}" "IP.TCP"
|
||||
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
|
||||
"${SemanticAttributes.NET_PEER_PORT.key}" port
|
||||
"${SemanticAttributes.DB_CONNECTION_STRING.key}" "redis://127.0.0.1:$port"
|
||||
"${SemanticAttributes.DB_SYSTEM.key}" "redis"
|
||||
"${SemanticAttributes.DB_STATEMENT.key}" "MSET key1 ? key2 ?"
|
||||
}
|
||||
event(0) {
|
||||
eventName "redis.encode.start"
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.lettuce.v5_1
|
||||
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
class RedisCommandNormalizerTest extends Specification {
|
||||
@Unroll
|
||||
def "should normalize #expected"() {
|
||||
when:
|
||||
def normalised = RedisCommandNormalizer.normalize(command, args)
|
||||
|
||||
then:
|
||||
normalised == expected
|
||||
|
||||
where:
|
||||
command | args | expected
|
||||
// Connection
|
||||
"AUTH" | ["password"] | "AUTH ?"
|
||||
"HELLO" | ["3", "AUTH", "username", "password"] | "HELLO 3 AUTH ? ?"
|
||||
"HELLO" | ["3"] | "HELLO 3"
|
||||
// Hashes
|
||||
"HMSET" | ["hash", "key1", "value1", "key2", "value2"] | "HMSET hash key1 ? key2 ?"
|
||||
"HSET" | ["hash", "key1", "value1", "key2", "value2"] | "HSET hash key1 ? key2 ?"
|
||||
"HSETNX" | ["hash", "key", "value"] | "HSETNX hash key ?"
|
||||
// HyperLogLog
|
||||
"PFADD" | ["hll", "a", "b", "c"] | "PFADD hll ? ? ?"
|
||||
// Keys
|
||||
"MIGRATE" | ["127.0.0.1", "4242", "key", "0", "5000", "AUTH", "password"] | "MIGRATE 127.0.0.1 4242 key 0 5000 AUTH ?"
|
||||
"RESTORE" | ["key", "42", "value"] | "RESTORE key 42 ?"
|
||||
// Lists
|
||||
"LINSERT" | ["list", "BEFORE", "value1", "value2"] | "LINSERT list BEFORE ? ?"
|
||||
"LPOS" | ["list", "value"] | "LPOS list ?"
|
||||
"LPUSH" | ["list", "value1", "value2"] | "LPUSH list ? ?"
|
||||
"LPUSHX" | ["list", "value1", "value2"] | "LPUSHX list ? ?"
|
||||
"LREM" | ["list", "2", "value"] | "LREM list ? ?"
|
||||
"LSET" | ["list", "2", "value"] | "LSET list ? ?"
|
||||
"RPUSH" | ["list", "value1", "value2"] | "RPUSH list ? ?"
|
||||
"RPUSHX" | ["list", "value1", "value2"] | "RPUSHX list ? ?"
|
||||
// Pub/Sub
|
||||
"PUBLISH" | ["channel", "message"] | "PUBLISH channel ?"
|
||||
// Scripting
|
||||
"EVAL" | ["script", "2", "key1", "key2", "value"] | "EVAL script 2 key1 key2 ?"
|
||||
"EVALSHA" | ["sha1", "0", "value1", "value2"] | "EVALSHA sha1 0 ? ?"
|
||||
// Sets
|
||||
"SADD" | ["set", "value1", "value2"] | "SADD set ? ?"
|
||||
"SISMEMBER" | ["set", "value"] | "SISMEMBER set ?"
|
||||
"SMISMEMBER" | ["set", "value1", "value2"] | "SMISMEMBER set ? ?"
|
||||
"SMOVE" | ["set1", "set2", "value"] | "SMOVE set1 set2 ?"
|
||||
"SREM" | ["set", "value1", "value2"] | "SREM set ? ?"
|
||||
// Server
|
||||
"CONFIG" | ["SET", "masterpassword", "password"] | "CONFIG SET masterpassword ?"
|
||||
// Sorted Sets
|
||||
"ZADD" | ["sset", "1", "value1", "2", "value2"] | "ZADD sset ? ? ? ?"
|
||||
"ZCOUNT" | ["sset", "1", "10"] | "ZCOUNT sset ? ?"
|
||||
"ZINCRBY" | ["sset", "1", "value"] | "ZINCRBY sset ? ?"
|
||||
"ZLEXCOUNT" | ["sset", "1", "10"] | "ZLEXCOUNT sset ? ?"
|
||||
"ZMSCORE" | ["sset", "value1", "value2"] | "ZMSCORE sset ? ?"
|
||||
"ZRANGEBYLEX" | ["sset", "1", "10"] | "ZRANGEBYLEX sset ? ?"
|
||||
"ZRANGEBYSCORE" | ["sset", "1", "10"] | "ZRANGEBYSCORE sset ? ?"
|
||||
"ZRANK" | ["sset", "value"] | "ZRANK sset ?"
|
||||
"ZREM" | ["sset", "value1", "value2"] | "ZREM sset ? ?"
|
||||
"ZREMRANGEBYLEX" | ["sset", "1", "10"] | "ZREMRANGEBYLEX sset ? ?"
|
||||
"ZREMRANGEBYSCORE" | ["sset", "1", "10"] | "ZREMRANGEBYSCORE sset ? ?"
|
||||
"ZREVRANGEBYLEX" | ["sset", "1", "10"] | "ZREVRANGEBYLEX sset ? ?"
|
||||
"ZREVRANGEBYSCORE" | ["sset", "1", "10"] | "ZREVRANGEBYSCORE sset ? ?"
|
||||
"ZREVRANK" | ["sset", "value"] | "ZREVRANK sset ?"
|
||||
"ZSCORE" | ["sset", "value"] | "ZSCORE sset ?"
|
||||
// Streams
|
||||
"XADD" | ["stream", "*", "key1", "value1", "key2", "value2"] | "XADD stream * key1 ? key2 ?"
|
||||
// Strings
|
||||
"APPEND" | ["key", "value"] | "APPEND key ?"
|
||||
"GETSET" | ["key", "value"] | "GETSET key ?"
|
||||
"MSET" | ["key1", "value1", "key2", "value2"] | "MSET key1 ? key2 ?"
|
||||
"MSETNX" | ["key1", "value1", "key2", "value2"] | "MSETNX key1 ? key2 ?"
|
||||
"PSETEX" | ["key", "10000", "value"] | "PSETEX key 10000 ?"
|
||||
"SET" | ["key", "value"] | "SET key ?"
|
||||
"SETEX" | ["key", "10", "value"] | "SETEX key 10 ?"
|
||||
"SETNX" | ["key", "value"] | "SETNX key ?"
|
||||
"SETRANGE" | ["key", "42", "value"] | "SETRANGE key ? ?"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "should keep all arguments of #command"() {
|
||||
given:
|
||||
def args = ["arg1", "arg 2"]
|
||||
|
||||
when:
|
||||
def normalised = RedisCommandNormalizer.normalize(command, args)
|
||||
|
||||
then:
|
||||
normalised == command + " " + args.join(" ")
|
||||
|
||||
where:
|
||||
command << [
|
||||
// Cluster
|
||||
"CLUSTER", "READONLY", "READWRITE",
|
||||
// Connection
|
||||
"CLIENT", "ECHO", "PING", "QUIT", "SELECT",
|
||||
// Geo
|
||||
"GEOADD", "GEODIST", "GEOHASH", "GEOPOS", "GEORADIUS", "GEORADIUSBYMEMBER",
|
||||
// Hashes
|
||||
"HDEL", "HEXISTS", "HGET", "HGETALL", "HINCRBY", "HINCRBYFLOAT", "HKEYS", "HLEN", "HMGET",
|
||||
"HSCAN", "HSTRLEN", "HVALS",
|
||||
// HyperLogLog
|
||||
"PFCOUNT", "PFMERGE",
|
||||
// Keys
|
||||
"DEL", "DUMP", "EXISTS", "EXPIRE", "EXPIREAT", "KEYS", "MOVE", "OBJECT", "PERSIST", "PEXPIRE",
|
||||
"PEXPIREAT", "PTTL", "RANDOMKEY", "RENAME", "RENAMENX", "RESTORE", "SCAN", "SORT", "TOUCH",
|
||||
"TTL", "TYPE", "UNLINK", "WAIT",
|
||||
// Lists
|
||||
"BLMOVE", "BLPOP", "BRPOP", "BRPOPLPUSH", "LINDEX", "LLEN", "LMOVE", "LPOP", "LRANGE",
|
||||
"LTRIM", "RPOP", "RPOPLPUSH",
|
||||
// Pub/Sub
|
||||
"PSUBSCRIBE", "PUBSUB", "PUNSUBSCRIBE", "SUBSCRIBE", "UNSUBSCRIBE",
|
||||
// Server
|
||||
"ACL", "BGREWRITEAOF", "BGSAVE", "COMMAND", "DBSIZE", "DEBUG", "FLUSHALL", "FLUSHDB", "INFO",
|
||||
"LASTSAVE", "LATENCY", "LOLWUT", "MEMORY", "MODULE", "MONITOR", "PSYNC", "REPLICAOF", "ROLE",
|
||||
"SAVE", "SHUTDOWN", "SLAVEOF", "SLOWLOG", "SWAPDB", "SYNC", "TIME",
|
||||
// Sets
|
||||
"SCARD", "SDIFF", "SDIFFSTORE", "SINTER", "SINTERSTORE", "SMEMBERS", "SPOP", "SRANDMEMBER",
|
||||
"SSCAN", "SUNION", "SUNIONSTORE",
|
||||
// Sorted Sets
|
||||
"BZPOPMAX", "BZPOPMIN", "ZCARD", "ZINTER", "ZINTERSTORE", "ZPOPMAX", "ZPOPMIN", "ZRANGE",
|
||||
"ZREMRANGEBYRANK", "ZREVRANGE", "ZSCAN", "ZUNION", "ZUNIONSTORE",
|
||||
// Streams
|
||||
"XACK", "XCLAIM", "XDEL", "XGROUP", "XINFO", "XLEN", "XPENDING", "XRANGE", "XREAD",
|
||||
"XREADGROUP", "XREVRANGE", "XTRIM",
|
||||
// Strings
|
||||
"BITCOUNT", "BITFIELD", "BITOP", "BITPOS", "DECR", "DECRBY", "GET", "GETBIT", "GETRANGE",
|
||||
"INCR", "INCRBY", "INCRBYFLOAT", "MGET", "SETBIT", "STRALGO", "STRLEN",
|
||||
// Transactions
|
||||
"DISCARD", "EXEC", "MULTI", "UNWATCH", "WATCH"
|
||||
]
|
||||
}
|
||||
|
||||
def "should mask all arguments of an unknown command"() {
|
||||
when:
|
||||
def normalised = RedisCommandNormalizer.normalize("NEWAUTH", ["password", "secret"])
|
||||
|
||||
then:
|
||||
normalised == "NEWAUTH ? ?"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue