Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AWS v2 DynamoDB instrumentation #343

Merged
merged 1 commit into from
Jul 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly don't know. @XiXiaPdx would need to help clear that up.

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