Skip to content

Commit

Permalink
Jedis 4.0.0 (#698)
Browse files Browse the repository at this point in the history
* open jedis version to verifyInstrumentation

* jedis 4.0.0+ instrumentation

* remove unnecessary trace

* implement suggested changes

* remove NewField usage from pubsub
  • Loading branch information
tbradellis authored Mar 3, 2022
1 parent 4c2e8da commit d7e2c27
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 1 deletion.
2 changes: 1 addition & 1 deletion instrumentation/jedis-3.0.0/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies {
verifyInstrumentation {
passes 'redis.clients:jedis:[3.0.0,4.0.0)'
fails 'redis.clients:jedis:[1.4.0,3.0.0)'
fails 'redis.clients:jedis:[4.0.0,)'
// fails 'redis.clients:jedis:[4.0.0,)'
excludeRegex 'redis.clients:jedis:.*-(m|rc|RC|beta)[0-9]*'
// there's something weird about how the verifier treats this version
exclude 'redis.clients:jedis:3.6.2'
Expand Down
24 changes: 24 additions & 0 deletions instrumentation/jedis-4.0.0/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.jedis-4.0.0' }
}

dependencies {
implementation(project(":agent-bridge"))
implementation(project(":agent-bridge-datastore"))
implementation(project(":newrelic-api"))
implementation(project(":newrelic-weaver-api"))
implementation("redis.clients:jedis:4.0.0")
}

verifyInstrumentation {
passes 'redis.clients:jedis:[4.0.0,)'
fails 'redis.clients:jedis:[1.4.0,3.8.0]'
excludeRegex 'redis.clients:jedis:.*-(m|rc|RC|beta)[0-9]*'
exclude 'redis.clients:jedis:3.6.2'

}

site {
title 'Jedis'
type 'Datastore'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
*
* * Copyright 2020 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/

package redis.clients.jedis;

import com.newrelic.agent.bridge.AgentBridge;
import com.newrelic.agent.bridge.datastore.DatastoreVendor;
import com.newrelic.api.agent.DatastoreParameters;
import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.NewField;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import redis.clients.jedis.commands.ProtocolCommand;

import java.nio.charset.StandardCharsets;
import java.util.logging.Level;

@SuppressWarnings({ "ResultOfMethodCallIgnored", "WeakerAccess", "unused" }) // Weaver.callOriginal(), matching signatures
@Weave(type = MatchType.BaseClass, originalName = "redis.clients.jedis.Connection")
public abstract class Connection_Instrumentation {

@NewField
private long db = 0;

abstract HostAndPort getHostAndPort();

public void disconnect() {
db = 0;
Weaver.callOriginal();
}

@Trace
public void sendCommand(final ProtocolCommand cmd, final byte[]... args) {
Weaver.callOriginal();

updateDbIndex(cmd, new String(args[0], StandardCharsets.UTF_8));

}

@Trace
public void sendCommand(final ProtocolCommand cmd, final String... args) {
Weaver.callOriginal();

updateDbIndex(cmd, args[0]);
}

@Trace(leaf = true)
public void sendCommand(final CommandArguments args) {
Weaver.callOriginal();

ProtocolCommand cmd = args.getCommand();
reportMethodAsExternal(cmd);

}

private void updateDbIndex(ProtocolCommand cmd, String arg0) {
try {
if (cmd == Protocol.Command.SELECT) {
db = Long.parseLong(arg0);
} else if (cmd == Protocol.Command.QUIT) {
db = 0;
}
} catch (Throwable t) {
AgentBridge.getAgent().getLogger().log(Level.FINER, t, "Unable to set DB index");
}
}

private void reportMethodAsExternal(ProtocolCommand command) {
String operation = "unknown";
try {

operation = new String(command.getRaw(), Protocol.CHARSET).toLowerCase();
} catch (Exception ignored) {
}

NewRelic.getAgent().getTracedMethod().reportAsExternal(DatastoreParameters
.product(DatastoreVendor.Redis.name())
.collection(null)
.operation(operation)
.instance(getHostAndPort().getHost(), getHostAndPort().getPort())
.databaseName(String.valueOf(db))
.build());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
*
* * Copyright 2020 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/

package redis.clients.jedis;

import com.newrelic.agent.bridge.datastore.DatastoreVendor;
import com.newrelic.api.agent.DatastoreParameters;
import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;

@SuppressWarnings({ "ResultOfMethodCallIgnored", "unused" })
@Weave(type = MatchType.ExactClass, originalName = "redis.clients.jedis.JedisPubSub")
public class JedisPubSub_Instrumentation {

private volatile Connection client;

public void proceed(Connection client, String... channels) {
Weaver.callOriginal();
}

public void proceedWithPatterns(Connection client, String... channels) {
Weaver.callOriginal();
}

@Trace
public void onMessage(String channel, String message) {
Weaver.callOriginal();

reportMethodAsExternal("message");
}

@Trace
public void onPMessage(String pattern, String channel, String message) {
Weaver.callOriginal();

reportMethodAsExternal("message");
}

@Trace
public void onSubscribe(String channel, int subscribedChannels) {
Weaver.callOriginal();

reportMethodAsExternal("subscribe");
}

@Trace
public void onUnsubscribe(String channel, int subscribedChannels) {
Weaver.callOriginal();

reportMethodAsExternal("unsubscribe");
}

@Trace
public void onPUnsubscribe(String pattern, int subscribedChannels) {
Weaver.callOriginal();

reportMethodAsExternal("unsubscribe");
}

@Trace
public void onPSubscribe(String pattern, int subscribedChannels) {
Weaver.callOriginal();

reportMethodAsExternal("subscribe");
}

private void reportMethodAsExternal(String commandName) {
NewRelic.getAgent().getTracedMethod().reportAsExternal(DatastoreParameters
.product(DatastoreVendor.Redis.name())
.collection(null)
.operation(commandName)
.instance(client.getHostAndPort().getHost(), client.getHostAndPort().getPort())
.build());

}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ include 'instrumentation:jedis-1.4.0'
include 'instrumentation:jedis-2.7.1'
include 'instrumentation:jedis-2.7.2'
include 'instrumentation:jedis-3.0.0'
include 'instrumentation:jedis-4.0.0'
include 'instrumentation:jersey-1'
include 'instrumentation:jersey-2'
include 'instrumentation:jersey-client-1'
Expand Down

0 comments on commit d7e2c27

Please sign in to comment.