From 25b16e44fdd300454f053bf3ecc85035b618ad74 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 5 May 2026 16:18:01 -0400 Subject: [PATCH] Avoid ClassCastException on every DynamoDB request in AwsSdkClientDecorator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `getValueForField("Key", String.class)` was called on every AWS SDK v2 request and a `ClassCastException` was caught on every DynamoDB Get/Put/Update/Delete item call (Key is `Map`). This forced the JVM to fill in a stack trace per request on a hot path. Gate the `Key` extraction to S3 (the only service whose top-level `Key` is a `String`), inline the helper, and drop the dead try/catch. Behavior for S3 is unchanged — `setObjectKey` already wrote the same tag the DSM-only branch was writing. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../aws/v2/AwsSdkClientDecorator.java | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-sdk-2.2/src/main/java/datadog/trace/instrumentation/aws/v2/AwsSdkClientDecorator.java b/dd-java-agent/instrumentation/aws-java/aws-java-sdk-2.2/src/main/java/datadog/trace/instrumentation/aws/v2/AwsSdkClientDecorator.java index f56c112de6c..b0c92a6c8e7 100644 --- a/dd-java-agent/instrumentation/aws-java/aws-java-sdk-2.2/src/main/java/datadog/trace/instrumentation/aws/v2/AwsSdkClientDecorator.java +++ b/dd-java-agent/instrumentation/aws-java/aws-java-sdk-2.2/src/main/java/datadog/trace/instrumentation/aws/v2/AwsSdkClientDecorator.java @@ -133,14 +133,14 @@ public Context onSdkRequest( // S3 request.getValueForField("Bucket", String.class).ifPresent(name -> setBucketName(span, name)); - if ("s3".equalsIgnoreCase(awsServiceName) && traceConfig().isDataStreamsEnabled()) { - request - .getValueForField("Key", String.class) - .ifPresent(key -> span.setTag(InstrumentationTags.AWS_OBJECT_KEY, key)); - span.setTag(Tags.HTTP_REQUEST_CONTENT_LENGTH, getRequestContentLength(httpRequest)); + if ("s3".equalsIgnoreCase(awsServiceName)) { + // gate "Key" extraction to S3 — DynamoDB's Key is Map, would CCE + request.getValueForField("Key", String.class).ifPresent(key -> setObjectKey(span, key)); + if (traceConfig().isDataStreamsEnabled()) { + span.setTag(Tags.HTTP_REQUEST_CONTENT_LENGTH, getRequestContentLength(httpRequest)); + } } - getRequestKey(request).ifPresent(key -> setObjectKey(span, key)); request .getValueForField("StorageClass", String.class) .ifPresent( @@ -279,17 +279,6 @@ private static void setBucketName(AgentSpan span, String name) { setPeerService(span, InstrumentationTags.AWS_BUCKET_NAME, name); } - private static Optional getRequestKey(SdkRequest request) { - Optional key = Optional.empty(); - try { - key = request.getValueForField("Key", String.class); - } catch (ClassCastException ignored) { - // Key is not always a string, like for dynamodb GetItemRequest - } - - return key; - } - private static void setObjectKey(AgentSpan span, String key) { span.setTag(InstrumentationTags.AWS_OBJECT_KEY, key); }