Skip to content

Commit

Permalink
Merge pull request #312 from newrelic/feature/report-external-conn-db
Browse files Browse the repository at this point in the history
[NR-299706] External connection reporting support for DynamoDB, Redis Client, Spymemcached
  • Loading branch information
IshikaDawda authored Nov 6, 2024
2 parents 44e9ba0 + b327ef8 commit 13201d9
Show file tree
Hide file tree
Showing 21 changed files with 374 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
import com.amazonaws.Response;
import com.amazonaws.http.ExecutionContext;
import com.amazonaws.http.HttpResponseHandler;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.newrelic.agent.security.instrumentation.dynamodb_1_11_390.DynamoDBUtil;
Expand All @@ -31,6 +35,12 @@ public abstract class AmazonDynamoDBClient_Instrumentation extends AmazonWebServ

public AmazonDynamoDBClient_Instrumentation(ClientConfiguration clientConfiguration) {
super(clientConfiguration);
try {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), endpoint.toString(), clientConfiguration.getLocalAddress().getHostAddress(),
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_1_11_390);
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_1_11_390, e.getMessage()), this.getClass().getName());
}
}

private <X, Y extends AmazonWebServiceRequest> Response<X> doInvoke(Request<Y> request, HttpResponseHandler<AmazonWebServiceResponse<X>> responseHandler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
import com.amazonaws.Response;
import com.amazonaws.http.ExecutionContext;
import com.amazonaws.http.HttpResponseHandler;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.newrelic.agent.security.instrumentation.dynamodb_1_11_453.DynamoDBUtil;
Expand All @@ -31,8 +35,13 @@ public abstract class AmazonDynamoDBClient_Instrumentation extends AmazonWebServ

public AmazonDynamoDBClient_Instrumentation(ClientConfiguration clientConfiguration) {
super(clientConfiguration);
try {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), endpoint.toString(), clientConfiguration.getLocalAddress().getHostAddress(),
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_1_11_453);
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_1_11_453, e.getMessage()), this.getClass().getName());
}
}

private <X, Y extends AmazonWebServiceRequest> Response<X> doInvoke(Request<Y> request, HttpResponseHandler<AmazonWebServiceResponse<X>> responseHandler, ExecutionContext executionContext, URI discoveredEndpoint, URI uriFromEndpointTrait) {
AbstractOperation noSQLOperation = null;
boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(request.hashCode());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
import com.amazonaws.Response;
import com.amazonaws.http.ExecutionContext;
import com.amazonaws.http.HttpResponseHandler;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.newrelic.agent.security.instrumentation.dynamodb_1_11_459.DynamoDBUtil;
Expand All @@ -31,6 +35,12 @@ public abstract class AmazonDynamoDBClient_Instrumentation extends AmazonWebServ

public AmazonDynamoDBClient_Instrumentation(ClientConfiguration clientConfiguration) {
super(clientConfiguration);
try {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), endpoint.toString(), clientConfiguration.getLocalAddress().getHostAddress(),
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_1_11_459);
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_1_11_459, e.getMessage()), this.getClass().getName());
}
}

private <X, Y extends AmazonWebServiceRequest> Response<X> doInvoke(Request<Y> request, HttpResponseHandler<AmazonWebServiceResponse<X>> responseHandler, ExecutionContext executionContext, URI discoveredEndpoint, URI uriFromEndpointTrait) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
import com.amazonaws.Response;
import com.amazonaws.http.ExecutionContext;
import com.amazonaws.http.HttpResponseHandler;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.newrelic.agent.security.instrumentation.dynamodb_1_11_80.DynamoDBUtil;
Expand All @@ -29,6 +33,11 @@ public abstract class AmazonDynamoDBClient_Instrumentation extends AmazonWebServ

public AmazonDynamoDBClient_Instrumentation(ClientConfiguration clientConfiguration) {
super(clientConfiguration);
try {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), null, clientConfiguration.getLocalAddress().getHostAddress(), ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_1_11_80);
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_1_11_80, e.getMessage()), this.getClass().getName());
}
}

// private <X, Y extends AmazonWebServiceRequest> Response<X> invoke(Request<Y> request, HttpResponseHandler<AmazonWebServiceResponse<X>> responseHandler, ExecutionContext executionContext) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package software.amazon.awssdk.services.dynamodb;

import com.newrelic.agent.security.instrumentation.dynamodb_210.DynamoDBUtil;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.client.config.SdkClientOption;

import java.net.URI;

@Weave(originalName = "software.amazon.awssdk.services.dynamodb.DefaultDynamoDbAsyncClient", type = MatchType.ExactClass)
final class DefaultDynamoDbAsyncClient_Instrumentation {

protected DefaultDynamoDbAsyncClient_Instrumentation(SdkClientConfiguration clientConfiguration) {
try {
URI endpoint = clientConfiguration != null ? clientConfiguration.option(SdkClientOption.ENDPOINT) : null;
if (endpoint != null) {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), null, null,
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_2_1_0);
}
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_2_1_0, e.getMessage()), this.getClass().getName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package software.amazon.awssdk.services.dynamodb;

import com.newrelic.agent.security.instrumentation.dynamodb_210.DynamoDBUtil;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.client.config.SdkClientOption;

import java.net.URI;

@Weave(originalName = "software.amazon.awssdk.services.dynamodb.DefaultDynamoDbClient", type = MatchType.ExactClass)
final class DefaultDynamoDbClient_Instrumentation {

protected DefaultDynamoDbClient_Instrumentation(SdkClientConfiguration clientConfiguration) {
try {
URI endpoint = clientConfiguration != null ? clientConfiguration.option(SdkClientOption.ENDPOINT) : null;
if (endpoint != null) {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), null, null,
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_2_1_0);
}
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_2_1_0, e.getMessage()), this.getClass().getName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package software.amazon.awssdk.services.dynamodb;

import com.newrelic.agent.security.instrumentation.dynamodb_212.DynamoDBUtil;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.client.config.SdkClientOption;

import java.net.URI;

@Weave(originalName = "software.amazon.awssdk.services.dynamodb.DefaultDynamoDbAsyncClient", type = MatchType.ExactClass)
final class DefaultDynamoDbAsyncClient_Instrumentation {

protected DefaultDynamoDbAsyncClient_Instrumentation(SdkClientConfiguration clientConfiguration) {
try {
URI endpoint = clientConfiguration != null ? clientConfiguration.option(SdkClientOption.ENDPOINT) : null;
if (endpoint != null) {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), null, null,
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_2_1_2);
}
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_2_1_2, e.getMessage()), this.getClass().getName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package software.amazon.awssdk.services.dynamodb;

import com.newrelic.agent.security.instrumentation.dynamodb_212.DynamoDBUtil;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.client.config.SdkClientOption;

import java.net.URI;

@Weave(originalName = "software.amazon.awssdk.services.dynamodb.DefaultDynamoDbClient", type = MatchType.ExactClass)
final class DefaultDynamoDbClient_Instrumentation {

protected DefaultDynamoDbClient_Instrumentation(SdkClientConfiguration clientConfiguration) {
try {
URI endpoint = clientConfiguration != null ? clientConfiguration.option(SdkClientOption.ENDPOINT) : null;
if (endpoint != null) {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), null, null,
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_2_1_2);
}
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_2_1_2, e.getMessage()), this.getClass().getName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package software.amazon.awssdk.services.dynamodb;

import com.newrelic.agent.security.instrumentation.dynamodb_215.DynamoDBUtil;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.WeaveAllConstructors;
import com.newrelic.api.agent.weaver.Weaver;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.client.config.SdkClientOption;

import java.net.URI;

@Weave(originalName = "software.amazon.awssdk.services.dynamodb.DefaultDynamoDbAsyncClient", type = MatchType.ExactClass)
final class DefaultDynamoDbAsyncClient_Instrumentation {

private final SdkClientConfiguration clientConfiguration = Weaver.callOriginal();

@WeaveAllConstructors
protected DefaultDynamoDbAsyncClient_Instrumentation() {
try {
URI endpoint = clientConfiguration != null ? clientConfiguration.option(SdkClientOption.ENDPOINT) : null;
if (endpoint != null) {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), null, null,
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_2_15_34);
}
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_2_15_34, e.getMessage()), this.getClass().getName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package software.amazon.awssdk.services.dynamodb;

import com.newrelic.agent.security.instrumentation.dynamodb_215.DynamoDBUtil;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.WeaveAllConstructors;
import com.newrelic.api.agent.weaver.Weaver;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.client.config.SdkClientOption;

import java.net.URI;

@Weave(originalName = "software.amazon.awssdk.services.dynamodb.DefaultDynamoDbClient", type = MatchType.ExactClass)
final class DefaultDynamoDbClient_Instrumentation {

private final SdkClientConfiguration clientConfiguration = Weaver.callOriginal();

@WeaveAllConstructors
protected DefaultDynamoDbClient_Instrumentation() {
try {
URI endpoint = clientConfiguration != null ? clientConfiguration.option(SdkClientOption.ENDPOINT) : null;
if (endpoint != null) {
NewRelicSecurity.getAgent().recordExternalConnection(endpoint.getHost(), endpoint.getPort(), null, null,
ExternalConnectionType.DATABASE_CONNECTION.name(), DynamoDBUtil.DYNAMODB_2_15_34);
}
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, DynamoDBUtil.DYNAMODB_2_15_34, e.getMessage()), this.getClass().getName());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
Expand All @@ -13,6 +15,19 @@

@Weave(type = MatchType.BaseClass, originalName = "redis.clients.jedis.Connection")
public abstract class Connection_Instrumentation {

public abstract int getPort();
public abstract String getHost();

public void connect() {
Weaver.callOriginal();
try {
NewRelicSecurity.getAgent().recordExternalConnection(getHost(), getPort(), null, null, ExternalConnectionType.DATABASE_CONNECTION.name(), "JEDIS-1.4.0");
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, "JEDIS-1.4.0", e.getMessage()), this.getClass().getName());
}
}

protected Connection sendCommand(final Protocol.Command cmd, final byte[]... args) {
boolean isLockAcquired = JedisHelper.acquireLockIfPossible(cmd.hashCode());
AbstractOperation operation = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,33 @@
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.ExternalConnectionType;
import com.newrelic.api.agent.security.utils.logging.LogLevel;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import redis.clients.jedis.Connection;
import redis.clients.jedis.Protocol;

import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import static com.newrelic.agent.security.instrumentation.jedis_2_7_1.JedisHelper.NR_SEC_CUSTOM_ATTRIB_NAME;

@Weave(type = MatchType.BaseClass, originalName = "redis.clients.jedis.Connection")
public abstract class Connection_Instrumentation {

public abstract Socket getSocket();

public abstract int getPort();
public abstract String getHost();

public void connect() {
Weaver.callOriginal();
try {
NewRelicSecurity.getAgent().recordExternalConnection(getHost(), getPort(), null, getSocket().getInetAddress().getHostAddress(), ExternalConnectionType.DATABASE_CONNECTION.name(), "JEDIS-2.7.1");
} catch (Exception e) {
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_DETECTING_CONNECTION_STATS, "JEDIS-2.7.1", e.getMessage()), this.getClass().getName());
}
}

protected Connection sendCommand(final ProtocolCommand cmd, final byte[]... args) {
boolean isLockAcquired = JedisHelper.acquireLockIfPossible(cmd.hashCode());
AbstractOperation operation = null;
Expand Down
1 change: 1 addition & 0 deletions instrumentation-security/jedis-3.0.0/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ dependencies {

verifyInstrumentation {
passes 'redis.clients:jedis:[3.0.0,4.0.0)'
excludeRegex(".*(rc|beta|RC).*")
}

site {
Expand Down
Loading

0 comments on commit 13201d9

Please sign in to comment.