Skip to content

Commit

Permalink
Add AWS v2 DynamoDB instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
XiXiaPdx authored and twcrone committed Jul 14, 2021
1 parent 4635c39 commit e6ad4a9
Show file tree
Hide file tree
Showing 8 changed files with 1,036 additions and 0 deletions.
46 changes: 46 additions & 0 deletions instrumentation/aws-java-sdk-dynamodb-2.15.34/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
dependencies {
implementation(project(":agent-bridge"))
implementation(project(":agent-bridge-datastore"))

implementation platform('software.amazon.awssdk:bom:2.16.81')
implementation("software.amazon.awssdk:dynamodb:2.16.81")
testImplementation("com.amazonaws:DynamoDBLocal:1.12.0")
testImplementation("com.almworks.sqlite4java:sqlite4java:1.0.392")
testImplementation("com.almworks.sqlite4java:libsqlite4java-osx:1.0.392")
testImplementation("com.almworks.sqlite4java:libsqlite4java-linux-i386:1.0.392")
testImplementation("com.almworks.sqlite4java:libsqlite4java-linux-amd64:1.0.392")

}

repositories {
mavenCentral()
maven {
url 'https://s3-us-west-2.amazonaws.com/dynamodb-local/release'
}
}

jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.aws-java-sdk-dynamodb-2.15.34' }
}

verifyInstrumentation {
passes 'software.amazon.awssdk:dynamodb:[2.1.0,)'
}

task copyNativeDeps(type: Copy) {
from(configurations.testCompileClasspath) {
include "*.so"
include "*.dylib"
}
into "build/nr-native-libs"
}

test {
dependsOn copyNativeDeps
jvmArgs(["-Dsqlite4java.library.path=build/nr-native-libs"])
}

site {
title 'AWS DynamoDB'
type 'Datastore'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.nr.instrumentation.dynamodb_v2;

import com.newrelic.agent.bridge.datastore.DatastoreVendor;
import com.newrelic.api.agent.DatastoreParameters;
import com.newrelic.api.agent.TracedMethod;

import java.net.URI;

public abstract class DynamoDBMetricUtil {

private static final String PRODUCT = DatastoreVendor.DynamoDB.name();
private static final String INSTANCE_HOST = "amazon";
private static final String INSTANCE_ID = "dynamodb";

public static void metrics(TracedMethod tracedMethod, String operation, String collection, URI endpoint) {
String host = endpoint == null ? INSTANCE_HOST : endpoint.getHost();
String port = endpoint == null ? INSTANCE_ID : String.valueOf(getPort(endpoint));

DatastoreParameters params = DatastoreParameters
.product(PRODUCT)
.collection(collection)
.operation(operation)
.instance(host, port)
.noDatabaseName()
.build();

tracedMethod.reportAsExternal(params);
}

private static int getPort(URI endpoint) {
if (endpoint.getPort() > 0) {
return endpoint.getPort();
}

final String scheme = endpoint.getScheme();
if ("http".equalsIgnoreCase(scheme)) {
return 80;
} else if ("https".equalsIgnoreCase(scheme)) {
return 443;
}
return -1;
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package software.amazon.awssdk.services.dynamodb;

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;
import com.nr.instrumentation.dynamodb_v2.DynamoDBMetricUtil;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.client.config.SdkClientOption;
import software.amazon.awssdk.services.dynamodb.model.*;

import java.net.URI;
import java.util.concurrent.CompletableFuture;

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

private final SdkClientConfiguration clientConfiguration = Weaver.callOriginal();

@Trace
public CompletableFuture<ScanResponse> scan(ScanRequest scanRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "scan", scanRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<PutItemResponse> putItem(PutItemRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "putItem", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<GetItemResponse> getItem(GetItemRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "getItem", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<DeleteItemResponse> deleteItem(DeleteItemRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "deleteItem", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<ListTablesResponse> listTables(ListTablesRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "listTables", request.exclusiveStartTableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<DescribeTableResponse> describeTable(DescribeTableRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "describeTable", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<CreateTableResponse> createTable(CreateTableRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "createTable", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<DeleteTableResponse> deleteTable(DeleteTableRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "deleteTable", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<BatchGetItemResponse> batchGetItem(BatchGetItemRequest batchGetItemRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "batchGetItem", "batch", getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<BatchWriteItemResponse> batchWriteItem(BatchWriteItemRequest batchWriteItemRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "batchWriteItem", "batch", getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<ListTagsOfResourceResponse> listTagsOfResource(ListTagsOfResourceRequest listTagsOfResourceRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "listTagsOfResource", listTagsOfResourceRequest.resourceArn(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<QueryResponse> query(QueryRequest queryRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "query", queryRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}


@Trace
public CompletableFuture<UpdateItemResponse> updateItem(UpdateItemRequest updateItemRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "updateItem", updateItemRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<UpdateTableResponse> updateTable(UpdateTableRequest updateTableRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "updateTable", updateTableRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<UpdateTimeToLiveResponse> updateTimeToLive(UpdateTimeToLiveRequest updateTimeToLiveRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "updateTimeToLive", updateTimeToLiveRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<DescribeLimitsResponse> describeLimits(DescribeLimitsRequest describeLimitsRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "describeLimits", null, getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<UntagResourceResponse> untagResource(UntagResourceRequest untagResourceRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "untagResource", untagResourceRequest.resourceArn(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<TagResourceResponse> tagResource(TagResourceRequest tagResourceRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "tagResource", tagResourceRequest.resourceArn(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CompletableFuture<DescribeTimeToLiveResponse> describeTimeToLive(DescribeTimeToLiveRequest describeTimeToLiveRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "describeTimeToLive", describeTimeToLiveRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

private URI getEndpoint() {
return clientConfiguration != null ? clientConfiguration.option(SdkClientOption.ENDPOINT) : null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package software.amazon.awssdk.services.dynamodb;

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;
import com.nr.instrumentation.dynamodb_v2.DynamoDBMetricUtil;
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
import software.amazon.awssdk.core.client.config.SdkClientOption;
import software.amazon.awssdk.services.dynamodb.model.*;

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();

@Trace
public GetItemResponse getItem(GetItemRequest getItemRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "getItem", getItemRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public ListTagsOfResourceResponse listTagsOfResource(ListTagsOfResourceRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "listTagsOfResource", null, getEndpoint());
return Weaver.callOriginal();
}

@Trace
public UntagResourceResponse untagResource(UntagResourceRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "untagResource", null, getEndpoint());
return Weaver.callOriginal();
}

@Trace
public BatchGetItemResponse batchGetItem(BatchGetItemRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "batchGetItem", "batch", getEndpoint());
return Weaver.callOriginal();
}

@Trace
public BatchWriteItemResponse batchWriteItem(BatchWriteItemRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "batchWriteItem", "batch", getEndpoint());
return Weaver.callOriginal();
}

@Trace
public PutItemResponse putItem(PutItemRequest putItemRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "putItem", putItemRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public DeleteItemResponse deleteItem(DeleteItemRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "deleteItem", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public ListTablesResponse listTables(ListTablesRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "listTables", request.exclusiveStartTableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public CreateTableResponse createTable(CreateTableRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "createTable", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public DeleteTableResponse deleteTable(DeleteTableRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "deleteTable", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public DescribeTableResponse describeTable(DescribeTableRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "describeTable", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public ScanResponse scan(ScanRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "scan", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public QueryResponse query(QueryRequest queryRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "query", queryRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public UpdateItemResponse updateItem(UpdateItemRequest updateItemRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "updateItem", updateItemRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public UpdateTableResponse updateTable(UpdateTableRequest updateTableRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "updateTable", updateTableRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public UpdateTimeToLiveResponse updateTimeToLive(UpdateTimeToLiveRequest request) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "updateTimeToLive", request.tableName(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public DescribeLimitsResponse describeLimits(DescribeLimitsRequest describeLimitsRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "describeLimits", null, getEndpoint());
return Weaver.callOriginal();
}

@Trace
public TagResourceResponse tagResource(TagResourceRequest tagResourceRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "tagResource", tagResourceRequest.resourceArn(), getEndpoint());
return Weaver.callOriginal();
}

@Trace
public DescribeTimeToLiveResponse describeTimeToLive(DescribeTimeToLiveRequest describeTimeToLiveRequest) {
DynamoDBMetricUtil.metrics(NewRelic.getAgent().getTracedMethod(), "describeTimeToLive", describeTimeToLiveRequest.tableName(), getEndpoint());
return Weaver.callOriginal();
}

private URI getEndpoint() {
return clientConfiguration != null ? clientConfiguration.option(SdkClientOption.ENDPOINT) : null;
}
}
Loading

0 comments on commit e6ad4a9

Please sign in to comment.