Update jedis-3.0 to Instrumenter API (#3124)
This commit is contained in:
parent
9ba984ffb8
commit
3c8874d536
|
@ -17,6 +17,9 @@ muzzle {
|
|||
dependencies {
|
||||
library "redis.clients:jedis:3.0.0"
|
||||
|
||||
compileOnly "com.google.auto.value:auto-value-annotations"
|
||||
annotationProcessor "com.google.auto.value:auto-value"
|
||||
|
||||
// ensures jedis-1.4 instrumentation does not load with jedis 3.0+ by failing
|
||||
// the tests in the event it does. The tests will end up with double spans
|
||||
testInstrumentation project(':instrumentation:jedis:jedis-1.4:javaagent')
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jedis.v3_0;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.db.RedisCommandSanitizer;
|
||||
import io.opentelemetry.instrumentation.api.tracer.DatabaseClientTracer;
|
||||
import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
|
||||
import io.opentelemetry.javaagent.instrumentation.jedis.v3_0.JedisClientTracer.CommandWithArgs;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes.DbSystemValues;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import redis.clients.jedis.Connection;
|
||||
import redis.clients.jedis.Protocol;
|
||||
import redis.clients.jedis.commands.ProtocolCommand;
|
||||
|
||||
public class JedisClientTracer extends DatabaseClientTracer<Connection, CommandWithArgs, String> {
|
||||
private static final JedisClientTracer TRACER = new JedisClientTracer();
|
||||
|
||||
private JedisClientTracer() {
|
||||
super(NetPeerAttributes.INSTANCE);
|
||||
}
|
||||
|
||||
public static JedisClientTracer tracer() {
|
||||
return TRACER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String sanitizeStatement(CommandWithArgs command) {
|
||||
return RedisCommandSanitizer.sanitize(command.getStringCommand(), command.getArgs());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String spanName(
|
||||
Connection connection, CommandWithArgs command, String sanitizedStatement) {
|
||||
return command.getStringCommand();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String dbSystem(Connection connection) {
|
||||
return DbSystemValues.REDIS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String dbConnectionString(Connection connection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InetSocketAddress peerAddress(Connection connection) {
|
||||
return new InetSocketAddress(connection.getHost(), connection.getPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String dbStatement(
|
||||
Connection connection, CommandWithArgs command, String sanitizedStatement) {
|
||||
return sanitizedStatement;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInstrumentationName() {
|
||||
return "io.opentelemetry.javaagent.jedis-3.0";
|
||||
}
|
||||
|
||||
public static final class CommandWithArgs {
|
||||
private final ProtocolCommand command;
|
||||
private final byte[][] args;
|
||||
|
||||
public CommandWithArgs(ProtocolCommand command, byte[][] args) {
|
||||
this.command = command;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
private String getStringCommand() {
|
||||
if (command instanceof Protocol.Command) {
|
||||
return ((Protocol.Command) command).name();
|
||||
} else {
|
||||
// Protocol.Command is the only implementation in the Jedis lib as of 3.1 but this will save
|
||||
// us if that changes
|
||||
return new String(command.getRaw(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
private List<?> getArgs() {
|
||||
return Arrays.asList(args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,8 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.jedis.v3_0;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
|
||||
import static io.opentelemetry.javaagent.instrumentation.jedis.v3_0.JedisClientTracer.tracer;
|
||||
import static io.opentelemetry.javaagent.instrumentation.jedis.v3_0.JedisInstrumenters.instrumenter;
|
||||
import static java.util.Arrays.asList;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.is;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -38,8 +39,7 @@ public class JedisConnectionInstrumentation implements TypeInstrumentation {
|
|||
.and(takesArgument(0, named("redis.clients.jedis.commands.ProtocolCommand")))
|
||||
.and(takesArgument(1, is(byte[][].class))),
|
||||
this.getClass().getName() + "$SendCommandAdvice");
|
||||
// FIXME: This instrumentation only incorporates sending the command, not processing the
|
||||
// result.
|
||||
// FIXME: This instrumentation only incorporates sending the command, not processing the result.
|
||||
}
|
||||
|
||||
public static class SendCommandAdvice {
|
||||
|
@ -49,32 +49,31 @@ public class JedisConnectionInstrumentation implements TypeInstrumentation {
|
|||
@Advice.This Connection connection,
|
||||
@Advice.Argument(0) ProtocolCommand command,
|
||||
@Advice.Argument(1) byte[][] args,
|
||||
@Advice.Local("otelJedisRequest") JedisRequest request,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope) {
|
||||
context =
|
||||
tracer()
|
||||
.startSpan(
|
||||
currentContext(),
|
||||
connection,
|
||||
new JedisClientTracer.CommandWithArgs(command, args));
|
||||
Context parentContext = currentContext();
|
||||
request = JedisRequest.create(connection, command, asList(args));
|
||||
if (!instrumenter().shouldStart(parentContext, request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
context = instrumenter().start(parentContext, request);
|
||||
scope = context.makeCurrent();
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Thrown Throwable throwable,
|
||||
@Advice.Local("otelJedisRequest") JedisRequest request,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope) {
|
||||
if (scope == null) {
|
||||
return;
|
||||
}
|
||||
scope.close();
|
||||
|
||||
if (throwable != null) {
|
||||
tracer().endExceptionally(context, throwable);
|
||||
} else {
|
||||
tracer().end(context);
|
||||
}
|
||||
scope.close();
|
||||
instrumenter().end(context, request, null, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jedis.v3_0;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.db.DbAttributesExtractor;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
final class JedisDbAttributesExtractor extends DbAttributesExtractor<JedisRequest, Void> {
|
||||
@Override
|
||||
protected String system(JedisRequest request) {
|
||||
return SemanticAttributes.DbSystemValues.REDIS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected String user(JedisRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String name(JedisRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String connectionString(JedisRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String statement(JedisRequest request) {
|
||||
return request.getStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String operation(JedisRequest request) {
|
||||
return request.getOperation();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jedis.v3_0;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.db.DbAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.db.DbSpanNameExtractor;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.instrumenter.PeerServiceAttributesExtractor;
|
||||
|
||||
public final class JedisInstrumenters {
|
||||
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.javaagent.jedis-3.0";
|
||||
|
||||
private static final Instrumenter<JedisRequest, Void> INSTRUMENTER;
|
||||
|
||||
static {
|
||||
DbAttributesExtractor<JedisRequest, Void> attributesExtractor =
|
||||
new JedisDbAttributesExtractor();
|
||||
SpanNameExtractor<JedisRequest> spanName = DbSpanNameExtractor.create(attributesExtractor);
|
||||
JedisNetAttributesExtractor netAttributesExtractor = new JedisNetAttributesExtractor();
|
||||
|
||||
INSTRUMENTER =
|
||||
Instrumenter.<JedisRequest, Void>newBuilder(
|
||||
GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanName)
|
||||
.addAttributesExtractor(attributesExtractor)
|
||||
.addAttributesExtractor(netAttributesExtractor)
|
||||
.addAttributesExtractor(PeerServiceAttributesExtractor.create(netAttributesExtractor))
|
||||
.newInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
}
|
||||
|
||||
public static Instrumenter<JedisRequest, Void> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
}
|
||||
|
||||
private JedisInstrumenters() {}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jedis.v3_0;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.net.NetAttributesExtractor;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
final class JedisNetAttributesExtractor extends NetAttributesExtractor<JedisRequest, Void> {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String transport(JedisRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String peerName(JedisRequest request, @Nullable Void response) {
|
||||
return request.getConnection().getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer peerPort(JedisRequest request, @Nullable Void response) {
|
||||
return request.getConnection().getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String peerIp(JedisRequest request, @Nullable Void response) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.jedis.v3_0;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import io.opentelemetry.instrumentation.api.db.RedisCommandSanitizer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import redis.clients.jedis.Connection;
|
||||
import redis.clients.jedis.Protocol;
|
||||
import redis.clients.jedis.commands.ProtocolCommand;
|
||||
|
||||
@AutoValue
|
||||
public abstract class JedisRequest {
|
||||
|
||||
public abstract Connection getConnection();
|
||||
|
||||
public abstract ProtocolCommand getCommand();
|
||||
|
||||
public abstract List<byte[]> getArgs();
|
||||
|
||||
public String getOperation() {
|
||||
ProtocolCommand command = getCommand();
|
||||
if (command instanceof Protocol.Command) {
|
||||
return ((Protocol.Command) command).name();
|
||||
} else {
|
||||
// Protocol.Command is the only implementation in the Jedis lib as of 3.1 but this will save
|
||||
// us if that changes
|
||||
return new String(command.getRaw(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
public String getStatement() {
|
||||
return RedisCommandSanitizer.sanitize(getOperation(), getArgs());
|
||||
}
|
||||
|
||||
public static JedisRequest create(
|
||||
Connection connection, ProtocolCommand command, List<byte[]> args) {
|
||||
return new AutoValue_JedisRequest(connection, command, args);
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ class Jedis30ClientTest extends AgentInstrumentationSpecification {
|
|||
attributes {
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "redis"
|
||||
"$SemanticAttributes.DB_STATEMENT.key" "SET foo ?"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.DB_OPERATION.key" "SET"
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ class Jedis30ClientTest extends AgentInstrumentationSpecification {
|
|||
attributes {
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "redis"
|
||||
"$SemanticAttributes.DB_STATEMENT.key" "SET foo ?"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.DB_OPERATION.key" "SET"
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ class Jedis30ClientTest extends AgentInstrumentationSpecification {
|
|||
attributes {
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "redis"
|
||||
"$SemanticAttributes.DB_STATEMENT.key" "GET foo"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.DB_OPERATION.key" "GET"
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ class Jedis30ClientTest extends AgentInstrumentationSpecification {
|
|||
attributes {
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "redis"
|
||||
"$SemanticAttributes.DB_STATEMENT.key" "SET foo ?"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.DB_OPERATION.key" "SET"
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ class Jedis30ClientTest extends AgentInstrumentationSpecification {
|
|||
attributes {
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "redis"
|
||||
"$SemanticAttributes.DB_STATEMENT.key" "RANDOMKEY"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.DB_OPERATION.key" "RANDOMKEY"
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue