@@ -32,6 +32,7 @@ import {
3232 MetricAttributeGenerator ,
3333 SERVICE_METRIC ,
3434} from './metric-attribute-generator' ;
35+ import { RegionalResourceArnParser } from './regional-resource-arn-parser' ;
3536import { SqsUrlParser } from './sqs-url-parser' ;
3637import { LAMBDA_APPLICATION_SIGNALS_REMOTE_ENVIRONMENT } from './aws-opentelemetry-configurator' ;
3738
@@ -112,8 +113,20 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
112113 AwsMetricAttributeGenerator . setService ( resource , span , attributes ) ;
113114 AwsMetricAttributeGenerator . setEgressOperation ( span , attributes ) ;
114115 AwsMetricAttributeGenerator . setRemoteServiceAndOperation ( span , attributes ) ;
115- AwsMetricAttributeGenerator . setRemoteResourceTypeAndIdentifier ( span , attributes ) ;
116+ const isRemoteResourceIdentifierPresent = AwsMetricAttributeGenerator . setRemoteResourceTypeAndIdentifier (
117+ span ,
118+ attributes
119+ ) ;
116120 AwsMetricAttributeGenerator . setRemoteEnvironment ( span , attributes ) ;
121+ if ( isRemoteResourceIdentifierPresent ) {
122+ const isAccountIdAndRegionPresent = AwsMetricAttributeGenerator . setRemoteResourceAccountIdAndRegion (
123+ span ,
124+ attributes
125+ ) ;
126+ if ( ! isAccountIdAndRegionPresent ) {
127+ AwsMetricAttributeGenerator . setRemoteResourceAccessKeyAndRegion ( span , attributes ) ;
128+ }
129+ }
117130 AwsMetricAttributeGenerator . setSpanKindForDependency ( span , attributes ) ;
118131 AwsMetricAttributeGenerator . setRemoteDbUser ( span , attributes ) ;
119132
@@ -369,7 +382,7 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
369382 * href="https://docs.aws.amazon.com/cloudcontrolapi/latest/userguide/supported-resources.html">AWS
370383 * Cloud Control resource format</a>.
371384 */
372- private static setRemoteResourceTypeAndIdentifier ( span : ReadableSpan , attributes : Attributes ) : void {
385+ private static setRemoteResourceTypeAndIdentifier ( span : ReadableSpan , attributes : Attributes ) : boolean {
373386 let remoteResourceType : AttributeValue | undefined ;
374387 let remoteResourceIdentifier : AttributeValue | undefined ;
375388 let cloudFormationIdentifier : AttributeValue | undefined ;
@@ -383,11 +396,27 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
383396 ) {
384397 remoteResourceType = NORMALIZED_DYNAMO_DB_SERVICE_NAME + '::Table' ;
385398 remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters ( awsTableNames [ 0 ] ) ;
399+ } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_DYNAMODB_TABLE_ARN ) ) {
400+ remoteResourceType = NORMALIZED_DYNAMO_DB_SERVICE_NAME + '::Table' ;
401+ remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
402+ this . extractResourceNameFromArn ( span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_DYNAMODB_TABLE_ARN ] ) ?. replace (
403+ 'table/' ,
404+ ''
405+ )
406+ ) ;
386407 } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_KINESIS_STREAM_NAME ) ) {
387408 remoteResourceType = NORMALIZED_KINESIS_SERVICE_NAME + '::Stream' ;
388409 remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
389410 span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_KINESIS_STREAM_NAME ]
390411 ) ;
412+ } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_KINESIS_STREAM_ARN ) ) {
413+ remoteResourceType = NORMALIZED_KINESIS_SERVICE_NAME + '::Stream' ;
414+ remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
415+ this . extractResourceNameFromArn ( span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_KINESIS_STREAM_ARN ] ) ?. replace (
416+ 'stream/' ,
417+ ''
418+ )
419+ ) ;
391420 } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_S3_BUCKET ) ) {
392421 remoteResourceType = NORMALIZED_S3_SERVICE_NAME + '::Bucket' ;
393422 remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
@@ -500,7 +529,10 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
500529 attributes [ AWS_ATTRIBUTE_KEYS . AWS_REMOTE_RESOURCE_TYPE ] = remoteResourceType ;
501530 attributes [ AWS_ATTRIBUTE_KEYS . AWS_REMOTE_RESOURCE_IDENTIFIER ] = remoteResourceIdentifier ;
502531 attributes [ AWS_ATTRIBUTE_KEYS . AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER ] = cloudFormationIdentifier ;
532+ return true ;
503533 }
534+
535+ return false ;
504536 }
505537
506538 /**
@@ -522,6 +554,56 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
522554 }
523555 }
524556
557+ private static setRemoteResourceAccountIdAndRegion ( span : ReadableSpan , attributes : Attributes ) : boolean {
558+ const ARN_ATTRIBUTES : string [ ] = [
559+ AWS_ATTRIBUTE_KEYS . AWS_DYNAMODB_TABLE_ARN ,
560+ AWS_ATTRIBUTE_KEYS . AWS_KINESIS_STREAM_ARN ,
561+ AWS_ATTRIBUTE_KEYS . AWS_SNS_TOPIC_ARN ,
562+ AWS_ATTRIBUTE_KEYS . AWS_SECRETSMANAGER_SECRET_ARN ,
563+ AWS_ATTRIBUTE_KEYS . AWS_STEPFUNCTIONS_STATEMACHINE_ARN ,
564+ AWS_ATTRIBUTE_KEYS . AWS_STEPFUNCTIONS_ACTIVITY_ARN ,
565+ AWS_ATTRIBUTE_KEYS . AWS_LAMBDA_FUNCTION_ARN ,
566+ AWS_ATTRIBUTE_KEYS . AWS_BEDROCK_GUARDRAIL_ARN ,
567+ ] ;
568+ let remoteResourceAccountId : string | undefined = undefined ;
569+ let remoteResourceRegion : string | undefined = undefined ;
570+
571+ if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_SQS_QUEUE_URL ) ) {
572+ const sqsQueueUrl = AwsMetricAttributeGenerator . escapeDelimiters (
573+ span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_SQS_QUEUE_URL ]
574+ ) ;
575+ remoteResourceAccountId = SqsUrlParser . getAccountId ( sqsQueueUrl ) ;
576+ remoteResourceRegion = SqsUrlParser . getRegion ( sqsQueueUrl ) ;
577+ } else {
578+ for ( const attributeKey of ARN_ATTRIBUTES ) {
579+ if ( AwsSpanProcessingUtil . isKeyPresent ( span , attributeKey ) ) {
580+ const arn = span . attributes [ attributeKey ] ;
581+ remoteResourceAccountId = RegionalResourceArnParser . getAccountId ( arn ) ;
582+ remoteResourceRegion = RegionalResourceArnParser . getRegion ( arn ) ;
583+ break ;
584+ }
585+ }
586+ }
587+
588+ if ( remoteResourceAccountId !== undefined && remoteResourceRegion !== undefined ) {
589+ attributes [ AWS_ATTRIBUTE_KEYS . AWS_REMOTE_RESOURCE_ACCOUNT_ID ] = remoteResourceAccountId ;
590+ attributes [ AWS_ATTRIBUTE_KEYS . AWS_REMOTE_RESOURCE_REGION ] = remoteResourceRegion ;
591+ return true ;
592+ }
593+
594+ return false ;
595+ }
596+
597+ private static setRemoteResourceAccessKeyAndRegion ( span : ReadableSpan , attributes : Attributes ) : void {
598+ if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_AUTH_ACCESS_KEY ) ) {
599+ attributes [ AWS_ATTRIBUTE_KEYS . AWS_REMOTE_RESOURCE_ACCESS_KEY ] =
600+ span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_AUTH_ACCESS_KEY ] ;
601+ }
602+ if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_AUTH_REGION ) ) {
603+ attributes [ AWS_ATTRIBUTE_KEYS . AWS_REMOTE_RESOURCE_REGION ] = span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_AUTH_REGION ] ;
604+ }
605+ }
606+
525607 /**
526608 * RemoteResourceIdentifier is populated with rule <code>
527609 * ^[{db.name}|]?{address}[|{port}]?
0 commit comments