Standardize DB query normalizer property names (#1509)
* Standardize DB query normalizer property names And add normalizer configuration for Redis, Couchbase, Cassandra and Geode * apply code review comments
This commit is contained in:
parent
af5fb0c944
commit
e89942d430
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.cassandra.v3_0;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.api.db.QueryNormalizationConfig.isQueryNormalizationEnabled;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.ParseException;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.SqlNormalizer;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -12,8 +14,12 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
public final class CassandraQueryNormalizer {
|
||||
private static final Logger log = LoggerFactory.getLogger(CassandraQueryNormalizer.class);
|
||||
private static final boolean NORMALIZATION_ENABLED = isQueryNormalizationEnabled("cassandra");
|
||||
|
||||
public static String normalize(String query) {
|
||||
if (!NORMALIZATION_ENABLED) {
|
||||
return query;
|
||||
}
|
||||
try {
|
||||
return SqlNormalizer.normalize(query);
|
||||
} catch (ParseException e) {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.api.db.QueryNormalizationConfig.isQueryNormalizationEnabled;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.ParseException;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.SqlNormalizer;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -12,8 +14,12 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
public final class CassandraQueryNormalizer {
|
||||
private static final Logger log = LoggerFactory.getLogger(CassandraQueryNormalizer.class);
|
||||
private static final boolean NORMALIZATION_ENABLED = isQueryNormalizationEnabled("cassandra");
|
||||
|
||||
public static String normalize(String query) {
|
||||
if (!NORMALIZATION_ENABLED) {
|
||||
return query;
|
||||
}
|
||||
try {
|
||||
return SqlNormalizer.normalize(query);
|
||||
} catch (ParseException e) {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.couchbase.v2_0;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.api.db.QueryNormalizationConfig.isQueryNormalizationEnabled;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.ParseException;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.SqlNormalizer;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
|
@ -15,6 +17,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
public final class CouchbaseQueryNormalizer {
|
||||
private static final Logger log = LoggerFactory.getLogger(CouchbaseQueryNormalizer.class);
|
||||
private static final boolean NORMALIZATION_ENABLED = isQueryNormalizationEnabled("couchbase");
|
||||
|
||||
private static final Class<?> QUERY_CLASS;
|
||||
private static final Class<?> STATEMENT_CLASS;
|
||||
|
@ -118,6 +121,9 @@ public final class CouchbaseQueryNormalizer {
|
|||
}
|
||||
|
||||
private static String normalizeString(String query) {
|
||||
if (!NORMALIZATION_ENABLED || query == null) {
|
||||
return query;
|
||||
}
|
||||
try {
|
||||
return SqlNormalizer.normalize(query);
|
||||
} catch (ParseException e) {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.geode;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.api.db.QueryNormalizationConfig.isQueryNormalizationEnabled;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.ParseException;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.SqlNormalizer;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -12,10 +14,12 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
public final class GeodeQueryNormalizer {
|
||||
private static final Logger log = LoggerFactory.getLogger(GeodeQueryNormalizer.class);
|
||||
private static final boolean NORMALIZATION_ENABLED =
|
||||
isQueryNormalizationEnabled("geode", "geode-client");
|
||||
|
||||
public static String normalize(String query) {
|
||||
if (query == null) {
|
||||
return null;
|
||||
if (!NORMALIZATION_ENABLED || query == null) {
|
||||
return query;
|
||||
}
|
||||
try {
|
||||
return SqlNormalizer.normalize(query);
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.jdbc;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.config.Config;
|
||||
import static io.opentelemetry.javaagent.instrumentation.api.db.QueryNormalizationConfig.isQueryNormalizationEnabled;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.api.db.normalizer.SqlNormalizer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.sql.Connection;
|
||||
|
@ -17,8 +18,7 @@ public abstract class JDBCUtils {
|
|||
|
||||
private static final Logger log = LoggerFactory.getLogger(JDBCUtils.class);
|
||||
|
||||
private static final boolean SQL_NORMALIZER_ENABLED =
|
||||
Config.get().getBooleanProperty("sql.normalizer.enabled", true);
|
||||
private static final boolean NORMALIZATION_ENABLED = isQueryNormalizationEnabled("jdbc");
|
||||
|
||||
private static Field c3poField = null;
|
||||
|
||||
|
@ -71,7 +71,7 @@ public abstract class JDBCUtils {
|
|||
|
||||
/** @return null if the sql could not be normalized for any reason */
|
||||
public static String normalizeSql(String sql) {
|
||||
if (!SQL_NORMALIZER_ENABLED) {
|
||||
if (!NORMALIZATION_ENABLED) {
|
||||
return sql;
|
||||
}
|
||||
try {
|
||||
|
|
|
@ -18,6 +18,9 @@ import redis.clients.jedis.Protocol.Command;
|
|||
public class JedisClientTracer extends DatabaseClientTracer<Connection, CommandWithArgs> {
|
||||
public static final JedisClientTracer TRACER = new JedisClientTracer();
|
||||
|
||||
private final RedisCommandNormalizer commandNormalizer =
|
||||
new RedisCommandNormalizer("jedis", "redis");
|
||||
|
||||
@Override
|
||||
protected String spanName(Connection connection, CommandWithArgs query, String normalizedQuery) {
|
||||
return query.getStringCommand();
|
||||
|
@ -25,7 +28,7 @@ public class JedisClientTracer extends DatabaseClientTracer<Connection, CommandW
|
|||
|
||||
@Override
|
||||
protected String normalizeQuery(CommandWithArgs command) {
|
||||
return RedisCommandNormalizer.normalize(command.getStringCommand(), command.getArgs());
|
||||
return commandNormalizer.normalize(command.getStringCommand(), command.getArgs());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,9 @@ import redis.clients.jedis.commands.ProtocolCommand;
|
|||
public class JedisClientTracer extends DatabaseClientTracer<Connection, CommandWithArgs> {
|
||||
public static final JedisClientTracer TRACER = new JedisClientTracer();
|
||||
|
||||
private final RedisCommandNormalizer commandNormalizer =
|
||||
new RedisCommandNormalizer("jedis", "redis");
|
||||
|
||||
@Override
|
||||
protected String spanName(Connection connection, CommandWithArgs query, String normalizedQuery) {
|
||||
return query.getStringCommand();
|
||||
|
@ -27,7 +30,7 @@ public class JedisClientTracer extends DatabaseClientTracer<Connection, CommandW
|
|||
|
||||
@Override
|
||||
protected String normalizeQuery(CommandWithArgs command) {
|
||||
return RedisCommandNormalizer.normalize(command.getStringCommand(), command.getArgs());
|
||||
return commandNormalizer.normalize(command.getStringCommand(), command.getArgs());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,9 @@ public class LettuceDatabaseClientTracer
|
|||
extends LettuceAbstractDatabaseClientTracer<RedisCommand<?, ?, ?>> {
|
||||
public static final LettuceDatabaseClientTracer TRACER = new LettuceDatabaseClientTracer();
|
||||
|
||||
private final RedisCommandNormalizer commandNormalizer =
|
||||
new RedisCommandNormalizer("lettuce", "lettuce-5");
|
||||
|
||||
@Override
|
||||
protected String spanName(
|
||||
RedisURI connection, RedisCommand<?, ?, ?> query, String normalizedQuery) {
|
||||
|
@ -29,6 +32,6 @@ public class LettuceDatabaseClientTracer
|
|||
redisCommand.getArgs() == null
|
||||
? Collections.emptyList()
|
||||
: LettuceArgSplitter.splitArgs(redisCommand.getArgs().toCommandString());
|
||||
return RedisCommandNormalizer.normalize(command, args);
|
||||
return commandNormalizer.normalize(command, args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ public enum OpenTelemetryTracing implements Tracing {
|
|||
public static final io.opentelemetry.trace.Tracer TRACER =
|
||||
OpenTelemetry.getGlobalTracer("io.opentelemetry.auto.lettuce-5.1");
|
||||
|
||||
private static final RedisCommandNormalizer commandNormalizer =
|
||||
new RedisCommandNormalizer("lettuce", "lettuce-5", "lettuce-5.1");
|
||||
|
||||
@Override
|
||||
public TracerProvider getTracerProvider() {
|
||||
return OpenTelemetryTracerProvider.INSTANCE;
|
||||
|
@ -250,7 +253,7 @@ public enum OpenTelemetryTracing implements Tracing {
|
|||
public synchronized void finish() {
|
||||
if (span != null) {
|
||||
if (name != null) {
|
||||
String statement = RedisCommandNormalizer.normalize(name, splitArgs(args));
|
||||
String statement = commandNormalizer.normalize(name, splitArgs(args));
|
||||
span.setAttribute(SemanticAttributes.DB_STATEMENT, statement);
|
||||
}
|
||||
span.end();
|
||||
|
|
|
@ -22,6 +22,9 @@ public class RedissonClientTracer extends DatabaseClientTracer<RedisConnection,
|
|||
|
||||
public static final RedissonClientTracer TRACER = new RedissonClientTracer();
|
||||
|
||||
private final RedisCommandNormalizer commandNormalizer =
|
||||
new RedisCommandNormalizer("redisson", "redis");
|
||||
|
||||
@Override
|
||||
protected String spanName(RedisConnection connection, Object query, String normalizedQuery) {
|
||||
if (query instanceof CommandsData) {
|
||||
|
@ -65,7 +68,7 @@ public class RedissonClientTracer extends DatabaseClientTracer<RedisConnection,
|
|||
return UNKNOWN_COMMAND;
|
||||
}
|
||||
|
||||
private static String normalizeSingleCommand(CommandData<?, ?> command) {
|
||||
private String normalizeSingleCommand(CommandData<?, ?> command) {
|
||||
Object[] commandParams = command.getParams();
|
||||
List<Object> args = new ArrayList<>(commandParams.length + 1);
|
||||
if (command.getCommand().getSubName() != null) {
|
||||
|
@ -86,7 +89,7 @@ public class RedissonClientTracer extends DatabaseClientTracer<RedisConnection,
|
|||
args.add(param);
|
||||
}
|
||||
}
|
||||
return RedisCommandNormalizer.normalize(command.getCommand().getName(), args);
|
||||
return commandNormalizer.normalize(command.getCommand().getName(), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.api.db;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.config.Config;
|
||||
|
||||
/**
|
||||
* This class encapsulates query normalization property naming convention. Query normalization is
|
||||
* always enabled by default, you have to manually disable it.
|
||||
*/
|
||||
public final class QueryNormalizationConfig {
|
||||
|
||||
public static boolean isQueryNormalizationEnabled(String... instrumentationNames) {
|
||||
for (String instrumentationName : instrumentationNames) {
|
||||
if (!Config.get().getBooleanProperty(propertyName(instrumentationName), true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String propertyName(String instrumentationName) {
|
||||
return "otel.instrumentation." + instrumentationName + ".query.normalizer.enabled";
|
||||
}
|
||||
|
||||
private QueryNormalizationConfig() {}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.api.db;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.api.db.QueryNormalizationConfig.isQueryNormalizationEnabled;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
|
@ -312,7 +313,16 @@ public final class RedisCommandNormalizer {
|
|||
NORMALIZERS = unmodifiableMap(normalizers);
|
||||
}
|
||||
|
||||
public static String normalize(String command, List<?> args) {
|
||||
private final boolean normalizationEnabled;
|
||||
|
||||
public RedisCommandNormalizer(String... instrumentationNames) {
|
||||
this.normalizationEnabled = isQueryNormalizationEnabled(instrumentationNames);
|
||||
}
|
||||
|
||||
public String normalize(String command, List<?> args) {
|
||||
if (!normalizationEnabled) {
|
||||
return KeepAllArgs.INSTANCE.normalize(command, args);
|
||||
}
|
||||
return NORMALIZERS.getOrDefault(command.toUpperCase(), DEFAULT).normalize(command, args);
|
||||
}
|
||||
|
||||
|
@ -416,6 +426,4 @@ public final class RedisCommandNormalizer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RedisCommandNormalizer() {}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,35 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.api.db
|
||||
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
class RedisCommandNormalizerTest extends Specification {
|
||||
def normalizer = new RedisCommandNormalizer("redis")
|
||||
|
||||
def "should not normalize anything when turned off"() {
|
||||
given:
|
||||
def previousConfig = ConfigUtils.updateConfig({
|
||||
it.setProperty("otel.instrumentation.redis.query.normalizer.enabled", "false")
|
||||
})
|
||||
|
||||
def normalizer = new RedisCommandNormalizer("redis-instrumentation", "redis")
|
||||
|
||||
when:
|
||||
def result = normalizer.normalize("AUTH", ["user", "password"])
|
||||
|
||||
then:
|
||||
result == "AUTH user password"
|
||||
|
||||
cleanup:
|
||||
ConfigUtils.setConfig(previousConfig)
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "should normalize #expected"() {
|
||||
when:
|
||||
def normalised = RedisCommandNormalizer.normalize(command, args)
|
||||
def normalised = normalizer.normalize(command, args)
|
||||
|
||||
then:
|
||||
normalised == expected
|
||||
|
@ -90,7 +111,7 @@ class RedisCommandNormalizerTest extends Specification {
|
|||
def args = ["arg1", "arg 2"]
|
||||
|
||||
when:
|
||||
def normalised = RedisCommandNormalizer.normalize(command, args)
|
||||
def normalised = normalizer.normalize(command, args)
|
||||
|
||||
then:
|
||||
normalised == command + " " + args.join(" ")
|
||||
|
@ -140,7 +161,7 @@ class RedisCommandNormalizerTest extends Specification {
|
|||
|
||||
def "should mask all arguments of an unknown command"() {
|
||||
when:
|
||||
def normalised = RedisCommandNormalizer.normalize("NEWAUTH", ["password", "secret"])
|
||||
def normalised = normalizer.normalize("NEWAUTH", ["password", "secret"])
|
||||
|
||||
then:
|
||||
normalised == "NEWAUTH ? ?"
|
||||
|
|
Loading…
Reference in New Issue