1717using NewRelic . Agent . Extensions . Parsing ;
1818using NewRelic . Agent . Extensions . Providers . Wrapper ;
1919using NewRelic . Agent . Extensions . SystemExtensions ;
20+ using static Grpc . Core . ServerServiceDefinition ;
2021
2122namespace NewRelic . Agent . Core . OpenTelemetryBridge ;
2223
@@ -474,7 +475,8 @@ private static void ProcessClientDatabaseTags(ISegment segment, IAgent agent, dy
474475 "redis" => DatastoreVendor . Redis ,
475476 "azure.cosmosdb" => DatastoreVendor . CosmosDB ,
476477 "elasticsearch" => DatastoreVendor . Elasticsearch ,
477- "aws.dynamodb" => DatastoreVendor . DynamoDB ,
478+ "dynamodb" => DatastoreVendor . DynamoDB , // OpenTelemetry.Instrumentation.AWS produces "dynamodb" for db.system
479+ "aws.dynamodb" => DatastoreVendor . DynamoDB , // the otel spec says "aws.dynamodb" is the correct value for DynamoDB
478480 _ => DatastoreVendor . Other
479481 } ;
480482
@@ -484,6 +486,7 @@ private static void ProcessClientDatabaseTags(ISegment segment, IAgent agent, dy
484486 ISegmentData segmentData = vendor switch
485487 {
486488 DatastoreVendor . Elasticsearch => GetElasticSearchDatastoreSegmentData ( agent , tags , vendor , activityLogPrefix ) ,
489+ DatastoreVendor . DynamoDB => GetDynamoDbDatastoreSegmentData ( agent , activity , activityLogPrefix , tags , segment ) ,
487490 _ => GetDefaultDatastoreSegmentData ( agent , activity , activityLogPrefix , tags , vendor )
488491 } ;
489492
@@ -568,6 +571,40 @@ private static ISegmentData GetElasticSearchDatastoreSegmentData(IAgent agent, D
568571 return new DatastoreSegmentData ( agent . GetExperimentalApi ( ) . DatabaseService , parsedSqlStatement , string . Empty , connectionInfo ) ;
569572 }
570573
574+ private static ISegmentData GetDynamoDbDatastoreSegmentData ( IAgent agent , dynamic activity , string activityLogPrefix , Dictionary < string , object > tags , ISegment segment )
575+ {
576+ tags . TryGetAndRemoveTag < string > ( [ "aws.dynamodb.table_names" ] , out var tableNames ) ;
577+ if ( string . IsNullOrEmpty ( tableNames ) )
578+ {
579+ Log . Finest ( $ "DynamoDB { activityLogPrefix } is missing required tag for table names. Not creating a DatastoreSegmentData.") ;
580+ return null ;
581+ }
582+
583+ // DynamoDB operation is in rpc.method
584+ tags . TryGetAndRemoveTag < string > ( [ "rpc.method" ] , out var dbOperation ) ;
585+ if ( string . IsNullOrEmpty ( dbOperation ) )
586+ {
587+ Log . Finest ( $ "DynamoDB { activityLogPrefix } is missing required tag for operation. Not creating a DatastoreSegmentData.") ;
588+ return null ;
589+ }
590+
591+ // Add DynamoDB specific attributes to the segment
592+ segment . AddCloudSdkAttribute ( "aws.operation" , dbOperation ) ;
593+
594+ // spec says region is in cloud.region but it's not there currently
595+ if ( tags . TryGetAndRemoveTag < string > ( [ "cloud.region" ] , out var awsRegion ) )
596+ segment . AddCloudSdkAttribute ( "aws.region" , awsRegion ) ;
597+
598+ // requestId is in aws.request_id
599+ if ( tags . TryGetAndRemoveTag < string > ( [ "aws.request_id" ] , out var requestId ) )
600+ segment . AddCloudSdkAttribute ( "aws.requestId" , requestId ) ;
601+
602+ var parsedSqlStatement = new ParsedSqlStatement ( DatastoreVendor . DynamoDB , tableNames , dbOperation ) ;
603+
604+ Log . Finest ( $ "Created DatastoreSegmentData for DynamoDB { activityLogPrefix } ") ;
605+ return new DatastoreSegmentData ( agent . GetExperimentalApi ( ) . DatabaseService , parsedSqlStatement , string . Empty , null ) ;
606+ }
607+
571608 public static void AddExceptionEventInformationToSegment ( this ISegment segment , object originalActivity , IErrorService errorService )
572609 {
573610 // Exceptions recorded during an activity may be added as events on the activity. Not every way of recording
0 commit comments