Skip to content

Add db.collection.name to DynamoDB spans under stable database semconv#18853

Merged
trask merged 10 commits into
open-telemetry:mainfrom
chlos:egor/dynamodb-db-collection-name
Jun 11, 2026
Merged

Add db.collection.name to DynamoDB spans under stable database semconv#18853
trask merged 10 commits into
open-telemetry:mainfrom
chlos:egor/dynamodb-db-collection-name

Conversation

@chlos

@chlos chlos commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

When OTEL_SEMCONV_STABILITY_OPT_IN=database is set the aws-sdk-2.2 and aws-sdk-1.11 DynamoDB extractors already emit db.system.name and db.operation.name, but db.collection.name — the stable replacement for per-operation table identification — was never wired up, leaving it absent from all DynamoDB spans even after opting in.

What changed

DynamoDbAttributesExtractor (aws-sdk-2.2 and aws-sdk-1.11):

  • Under emitStableDatabaseSemconv(), extract and emit db.collection.name with the DynamoDB table name.
  • For single-table operations (GetItem, PutItem, Query, Scan, DeleteItem, etc.) the value is read from the TableName request field.
  • For batch operations (BatchGetItem, BatchWriteItem) the RequestItems map is inspected: a single-entry map yields the one table name; a multi-entry map emits "MULTIPLE_TABLES" in line with the OTel DB spec guidance on multi-collection operations.
  • The legacy aws.dynamodb.table_names attribute is unaffected and continues to be emitted regardless of the stability setting.

Tests:

  • AbstractAws2ClientCoreTest and AbstractDynamoDbClientTest both assert db.collection.name when running under emitStableDatabaseSemconv().

Motivation

The stable database semantic conventions define db.collection.name as the primary way to identify which table a DynamoDB operation targets. Without it, users who opt in via OTEL_SEMCONV_STABILITY_OPT_IN=database cannot filter or group DynamoDB spans by table name using stable attribute names, and dashboards built against the stable conventions show no table-level data.

Testing

Existing parameterized tests in AbstractAws2ClientCoreTest cover all single-table operations (CreateTable, DeleteItem, DeleteTable, GetItem, PutItem, Query, UpdateItem, Scan) with tableName="sometable". The stable-semconv branch of each assertion now includes db.collection.name = "sometable". The AbstractDynamoDbClientTest for aws-sdk-1.11 is updated analogously.

When OTEL_SEMCONV_STABILITY_OPT_IN=database is set the aws-sdk-2.2 and
aws-sdk-1.11 DynamoDb extractors already emit db.system.name and
db.operation.name, but db.collection.name (the stable replacement for
aws.dynamodb.table_names as the human-readable table identifier) was
never wired up.

For single-table operations (GetItem, PutItem, Query, Scan, etc.) the
table name is read from the TableName request field. For batch
operations (BatchGetItem, BatchWriteItem) the RequestItems map is
inspected: a single-entry map yields the one table name; a multi-entry
map emits "MULTIPLE_TABLES" per the OTel DB spec guidance on
multi-collection operations.

The aws.dynamodb.table_names attribute is unaffected and continues to
be emitted regardless of semconv stability setting.
Copilot AI review requested due to automatic review settings May 26, 2026 16:54
@chlos
chlos requested a review from a team as a code owner May 26, 2026 16:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR updates DynamoDB AWS SDK instrumentation to emit the stable database semantic convention attribute db.collection.name when stable DB semconv emission is enabled.

Changes:

  • Emit db.collection.name for DynamoDB spans in AWS SDK v1.11 and v2.2 instrumentations.
  • Update corresponding tests to assert db.collection.name under stable semconv emission.
  • Add table name extraction logic for AWS SDK v2.2 requests (including batch operations).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java Adds stable-semconv assertion for db.collection.name in DynamoDB request tests.
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/DynamoDbAttributesExtractor.java Emits db.collection.name for v2.2 and introduces request-based table name extraction.
instrumentation/aws-sdk/aws-sdk-1.11/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/AbstractDynamoDbClientTest.java Makes attribute list mutable and conditionally asserts db.collection.name.
instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/DynamoDbAttributesExtractor.java Emits db.collection.name for v1.11 when stable semconv is enabled and table name is available.

Comment on lines +76 to +83
// When there is exactly one table, return it; otherwise return the sentinel for multiple tables.
Optional<Map> requestItems = request.getValueForField("RequestItems", Map.class);
if (requestItems.isPresent() && !requestItems.get().isEmpty()) {
Map<?, ?> items = requestItems.get();
if (items.size() == 1) {
return items.keySet().iterator().next().toString();
}
return "MULTIPLE_TABLES";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the follow-up commit (e62118b). The MULTIPLE_TABLES sentinel has been removed — extractTableName now returns null for multi-table batch operations so db.collection.name is omitted entirely, and is only set when the batch targets exactly one table.

Comment on lines +63 to +64
@SuppressWarnings("rawtypes")
private static String extractTableName(ExecutionAttributes executionAttributes) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in e62118b. Replaced Optional<Map> (raw) and the method-level @SuppressWarnings("rawtypes") with Optional<?> + instanceof Map guard and a narrower @SuppressWarnings("unchecked") scoped to just the single cast line, as suggested.

}
// Batch operations (BatchGetItem, BatchWriteItem) use a map keyed by table names.
// When there is exactly one table, return it; otherwise return the sentinel for multiple tables.
Optional<Map> requestItems = request.getValueForField("RequestItems", Map.class);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same fix as above (e62118b) — duplicate comment on the same change.

Comment on lines +54 to +59
if (emitStableDatabaseSemconv()) {
String tableName = extractTableName(executionAttributes);
if (tableName != null) {
attributes.put(DB_COLLECTION_NAME, tableName);
}
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added in e62118b. testBatchGetItemWithMultipleTablesOmitsDbCollectionName in AbstractAws2ClientCoreTest covers the multi-table case, verifying that a two-table BatchGetItem produces aws.dynamodb.table_names but no db.collection.name. The single-table batch cases (BatchGetItem and BatchWriteItem) were already covered by the parameterised test in provideArguments, which now includes the db.collection.name = "sometable" assertion when emitStableDatabaseSemconv() is active.

- Drop MULTIPLE_TABLES sentinel: omit db.collection.name entirely when
  a batch operation targets more than one table, as the attribute is
  defined as a single collection identifier
- Replace @SuppressWarnings("rawtypes") on the method with a narrower
  @SuppressWarnings("unchecked") on the single Map cast, and retrieve
  via Optional<?> + instanceof guard instead of raw Optional<Map>
- Add testBatchGetItemWithMultipleTablesOmitsDbCollectionName to
  explicitly verify that a two-table BatchGetItem produces
  aws.dynamodb.table_names but no db.collection.name
@chlos
chlos marked this pull request as draft May 27, 2026 09:18
@linux-foundation-easycla

linux-foundation-easycla Bot commented May 27, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

chlos added 5 commits June 4, 2026 10:48
- Add explanatory comment to @SuppressWarnings("unchecked") in
  DynamoDbAttributesExtractor (aws-sdk-2.2 library) to satisfy the
  SuppressWarningsWithoutExplanation errorprone check.
- Reformat AbstractDynamoDbClientTest (aws-sdk-1.11 testing) to match
  Google Java Format style expected by spotless.

Co-Authored-By: Claude Sonnet 4.6 (1M context)
The span and metric assertions in DynamoDB tests were not updated when
db.collection.name was added to spans/metrics under stable database
semconv:

- AbstractAws2ClientRecordHttpErrorTest: add DB_COLLECTION_NAME to the
  span assertion for PutItem under emitStableDatabaseSemconv().
- AbstractAws2ClientCoreTest: add DB_COLLECTION_NAME to the
  assertDurationMetric expected keys (metric view includes it).
- AbstractDynamoDbClientTest (aws-sdk-1.11): same metric fix, plus
  merge the two-line equalTo() args to satisfy spotless.

Co-Authored-By: Claude Sonnet 4.6 (1M context)
- Change SemconvStability class import to a static import of
  emitStableDatabaseSemconv to satisfy spotless (Google Java Format
  prefers static imports for single-method references).
- Exclude DB_COLLECTION_NAME from the assertDurationMetric expected
  keys for ListTables, which has no target table and therefore no
  db.collection.name attribute on its metric point.

Co-Authored-By: Claude Sonnet 4.6 (1M context)
Co-Authored-By: Claude Sonnet 4.6 (1M context)
Co-Authored-By: Claude Sonnet 4.6 (1M context)
@chlos
chlos force-pushed the egor/dynamodb-db-collection-name branch from 53c0de2 to 4188f06 Compare June 4, 2026 09:48
@chlos
chlos marked this pull request as ready for review June 4, 2026 11:20
@laurit laurit added this to the v2.29.0 milestone Jun 4, 2026
@chlos
chlos force-pushed the egor/dynamodb-db-collection-name branch from ad33197 to 0ea9127 Compare June 5, 2026 09:15
@chlos

chlos commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Hi @laurit , are there any actions required from my side? Or you'll just merge the PR when it's time?

@laurit

laurit commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

@laurit

laurit commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@chlos no action is required, we'll merge it for the next release

Comment on lines +81 to +85
@SuppressWarnings("unchecked")
Set<String> tables = ((Map<String, ?>) requestItems.get()).keySet();
if (tables.size() == 1) {
return tables.iterator().next();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@chlos sorry for the late review, check out https://github.com/open-telemetry/semantic-conventions/blob/main/docs/db/database-spans.md

For batch operations, if the individual operations are known to have the same collection name then that collection name SHOULD be used.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i'm going to merge and i'll look into this a bit more and will tag you if I send a follow-up

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks Trask! Just for the record here are the follow-ups:

@trask
trask merged commit a5e6882 into open-telemetry:main Jun 11, 2026
95 checks passed
@otelbot

otelbot Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Thank you for your contribution @chlos! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants