Add db.collection.name to DynamoDB spans under stable database semconv#18853
Conversation
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.
There was a problem hiding this comment.
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.namefor DynamoDB spans in AWS SDK v1.11 and v2.2 instrumentations. - Update corresponding tests to assert
db.collection.nameunder 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. |
| // 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"; |
There was a problem hiding this comment.
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.
| @SuppressWarnings("rawtypes") | ||
| private static String extractTableName(ExecutionAttributes executionAttributes) { |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
Same fix as above (e62118b) — duplicate comment on the same change.
| if (emitStableDatabaseSemconv()) { | ||
| String tableName = extractTableName(executionAttributes); | ||
| if (tableName != null) { | ||
| attributes.put(DB_COLLECTION_NAME, tableName); | ||
| } | ||
| } |
There was a problem hiding this comment.
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
- 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)
53c0de2 to
4188f06
Compare
ad33197 to
0ea9127
Compare
|
Hi @laurit , are there any actions required from my side? Or you'll just merge the PR when it's time? |
|
@copilot resolve the merge conflicts in this pull request |
|
@chlos no action is required, we'll merge it for the next release |
| @SuppressWarnings("unchecked") | ||
| Set<String> tables = ((Map<String, ?>) requestItems.get()).keySet(); | ||
| if (tables.size() == 1) { | ||
| return tables.iterator().next(); | ||
| } |
There was a problem hiding this comment.
@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.
There was a problem hiding this comment.
i'm going to merge and i'll look into this a bit more and will tag you if I send a follow-up
There was a problem hiding this comment.
Thanks Trask! Just for the record here are the follow-ups:
Summary
When
OTEL_SEMCONV_STABILITY_OPT_IN=databaseis set theaws-sdk-2.2andaws-sdk-1.11DynamoDB extractors already emitdb.system.nameanddb.operation.name, butdb.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):emitStableDatabaseSemconv(), extract and emitdb.collection.namewith the DynamoDB table name.GetItem,PutItem,Query,Scan,DeleteItem, etc.) the value is read from theTableNamerequest field.BatchGetItem,BatchWriteItem) theRequestItemsmap 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.aws.dynamodb.table_namesattribute is unaffected and continues to be emitted regardless of the stability setting.Tests:
AbstractAws2ClientCoreTestandAbstractDynamoDbClientTestboth assertdb.collection.namewhen running underemitStableDatabaseSemconv().Motivation
The stable database semantic conventions define
db.collection.nameas the primary way to identify which table a DynamoDB operation targets. Without it, users who opt in viaOTEL_SEMCONV_STABILITY_OPT_IN=databasecannot 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
AbstractAws2ClientCoreTestcover all single-table operations (CreateTable,DeleteItem,DeleteTable,GetItem,PutItem,Query,UpdateItem,Scan) withtableName="sometable". The stable-semconv branch of each assertion now includesdb.collection.name = "sometable". TheAbstractDynamoDbClientTestfor aws-sdk-1.11 is updated analogously.