@@ -55,6 +55,10 @@ const NORMALIZED_DYNAMO_DB_SERVICE_NAME: string = 'AWS::DynamoDB';
55
55
const NORMALIZED_KINESIS_SERVICE_NAME : string = 'AWS::Kinesis' ;
56
56
const NORMALIZED_S3_SERVICE_NAME : string = 'AWS::S3' ;
57
57
const NORMALIZED_SQS_SERVICE_NAME : string = 'AWS::SQS' ;
58
+ const NORMALIZED_SNS_SERVICE_NAME : string = 'AWS::SNS' ;
59
+ const NORMALIZED_SECRETSMANAGER_SERVICE_NAME = 'AWS::SecretsManager' ;
60
+ const NORMALIZED_STEPFUNCTIONS_SERVICE_NAME = 'AWS::StepFunctions' ;
61
+ const NORMALIZED_LAMBDA_SERVICE_NAME = 'AWS::Lambda' ;
58
62
const NORMALIZED_BEDROCK_SERVICE_NAME : string = 'AWS::Bedrock' ;
59
63
const NORMALIZED_BEDROCK_RUNTIME_SERVICE_NAME : string = 'AWS::BedrockRuntime' ;
60
64
@@ -330,6 +334,8 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
330
334
BedrockAgent : NORMALIZED_BEDROCK_SERVICE_NAME ,
331
335
BedrockAgentRuntime : NORMALIZED_BEDROCK_SERVICE_NAME ,
332
336
BedrockRuntime : NORMALIZED_BEDROCK_RUNTIME_SERVICE_NAME ,
337
+ SecretsManager : NORMALIZED_SECRETSMANAGER_SERVICE_NAME ,
338
+ SFN : NORMALIZED_STEPFUNCTIONS_SERVICE_NAME ,
333
339
} ;
334
340
return awsSdkServiceMapping [ serviceName ] || 'AWS::' + serviceName ;
335
341
}
@@ -350,6 +356,7 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
350
356
private static setRemoteResourceTypeAndIdentifier ( span : ReadableSpan , attributes : Attributes ) : void {
351
357
let remoteResourceType : AttributeValue | undefined ;
352
358
let remoteResourceIdentifier : AttributeValue | undefined ;
359
+ let cloudFormationIdentifier : AttributeValue | undefined ;
353
360
354
361
if ( AwsSpanProcessingUtil . isAwsSDKSpan ( span ) ) {
355
362
const awsTableNames : AttributeValue | undefined = span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_DYNAMODB_TABLE_NAMES ] ;
@@ -370,16 +377,56 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
370
377
remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
371
378
span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_S3_BUCKET ]
372
379
) ;
380
+ } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_SNS_TOPIC_ARN ) ) {
381
+ const snsArn = span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_SNS_TOPIC_ARN ] ;
382
+
383
+ remoteResourceType = NORMALIZED_SNS_SERVICE_NAME + '::Topic' ;
384
+ remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
385
+ this . extractResourceNameFromArn ( snsArn )
386
+ ) ;
387
+ cloudFormationIdentifier = AwsMetricAttributeGenerator . escapeDelimiters ( snsArn ) ;
388
+ } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_SECRETSMANAGER_SECRET_ARN ) ) {
389
+ const secretsArn = span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_SECRETSMANAGER_SECRET_ARN ] ;
390
+
391
+ remoteResourceType = NORMALIZED_SECRETSMANAGER_SERVICE_NAME + '::Secret' ;
392
+ remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
393
+ this . extractResourceNameFromArn ( secretsArn )
394
+ ) ;
395
+ cloudFormationIdentifier = AwsMetricAttributeGenerator . escapeDelimiters ( secretsArn ) ;
396
+ } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_STEPFUNCTIONS_STATEMACHINE_ARN ) ) {
397
+ const stateMachineArn = span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_STEPFUNCTIONS_STATEMACHINE_ARN ] ;
398
+
399
+ remoteResourceType = NORMALIZED_STEPFUNCTIONS_SERVICE_NAME + '::StateMachine' ;
400
+ remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
401
+ this . extractResourceNameFromArn ( stateMachineArn )
402
+ ) ;
403
+ cloudFormationIdentifier = AwsMetricAttributeGenerator . escapeDelimiters ( stateMachineArn ) ;
404
+ } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_STEPFUNCTIONS_ACTIVITY_ARN ) ) {
405
+ const activityArn = span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_STEPFUNCTIONS_ACTIVITY_ARN ] ;
406
+
407
+ remoteResourceType = NORMALIZED_STEPFUNCTIONS_SERVICE_NAME + '::Activity' ;
408
+ remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
409
+ this . extractResourceNameFromArn ( activityArn )
410
+ ) ;
411
+ cloudFormationIdentifier = AwsMetricAttributeGenerator . escapeDelimiters ( activityArn ) ;
412
+ } else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_LAMBDA_RESOURCE_MAPPING_ID ) ) {
413
+ remoteResourceType = NORMALIZED_LAMBDA_SERVICE_NAME + '::EventSourceMapping' ;
414
+ remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
415
+ span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_LAMBDA_RESOURCE_MAPPING_ID ]
416
+ ) ;
373
417
} else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_SQS_QUEUE_NAME ) ) {
374
418
remoteResourceType = NORMALIZED_SQS_SERVICE_NAME + '::Queue' ;
375
419
remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
376
420
span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_SQS_QUEUE_NAME ]
377
421
) ;
378
422
} else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_SQS_QUEUE_URL ) ) {
379
- remoteResourceType = NORMALIZED_SQS_SERVICE_NAME + '::Queue' ;
380
- remoteResourceIdentifier = SqsUrlParser . getQueueName (
381
- AwsMetricAttributeGenerator . escapeDelimiters ( span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_SQS_QUEUE_URL ] )
423
+ const sqsQueueUrl = AwsMetricAttributeGenerator . escapeDelimiters (
424
+ span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_SQS_QUEUE_URL ]
382
425
) ;
426
+
427
+ remoteResourceType = NORMALIZED_SQS_SERVICE_NAME + '::Queue' ;
428
+ remoteResourceIdentifier = SqsUrlParser . getQueueName ( sqsQueueUrl ) ;
429
+ cloudFormationIdentifier = sqsQueueUrl ;
383
430
} else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_BEDROCK_AGENT_ID ) ) {
384
431
remoteResourceType = NORMALIZED_BEDROCK_SERVICE_NAME + '::Agent' ;
385
432
remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
@@ -390,11 +437,17 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
390
437
remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
391
438
span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_BEDROCK_DATA_SOURCE_ID ]
392
439
) ;
440
+ cloudFormationIdentifier = `${ AwsMetricAttributeGenerator . escapeDelimiters (
441
+ span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_BEDROCK_KNOWLEDGE_BASE_ID ]
442
+ ) } |${ remoteResourceIdentifier } `;
393
443
} else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_BEDROCK_GUARDRAIL_ID ) ) {
394
444
remoteResourceType = NORMALIZED_BEDROCK_SERVICE_NAME + '::Guardrail' ;
395
445
remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
396
446
span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_BEDROCK_GUARDRAIL_ID ]
397
447
) ;
448
+ cloudFormationIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
449
+ span . attributes [ AWS_ATTRIBUTE_KEYS . AWS_BEDROCK_GUARDRAIL_ARN ]
450
+ ) ;
398
451
} else if ( AwsSpanProcessingUtil . isKeyPresent ( span , AWS_ATTRIBUTE_KEYS . AWS_BEDROCK_KNOWLEDGE_BASE_ID ) ) {
399
452
remoteResourceType = NORMALIZED_BEDROCK_SERVICE_NAME + '::KnowledgeBase' ;
400
453
remoteResourceIdentifier = AwsMetricAttributeGenerator . escapeDelimiters (
@@ -414,6 +467,14 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
414
467
if ( remoteResourceType !== undefined && remoteResourceIdentifier !== undefined ) {
415
468
attributes [ AWS_ATTRIBUTE_KEYS . AWS_REMOTE_RESOURCE_TYPE ] = remoteResourceType ;
416
469
attributes [ AWS_ATTRIBUTE_KEYS . AWS_REMOTE_RESOURCE_IDENTIFIER ] = remoteResourceIdentifier ;
470
+
471
+ if ( AwsSpanProcessingUtil . isAwsSDKSpan ( span ) ) {
472
+ if ( cloudFormationIdentifier === undefined ) {
473
+ cloudFormationIdentifier = remoteResourceIdentifier ;
474
+ }
475
+
476
+ attributes [ AWS_ATTRIBUTE_KEYS . AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER ] = cloudFormationIdentifier ;
477
+ }
417
478
}
418
479
}
419
480
@@ -532,6 +593,16 @@ export class AwsMetricAttributeGenerator implements MetricAttributeGenerator {
532
593
return input . split ( '^' ) . join ( '^^' ) . split ( '|' ) . join ( '^|' ) ;
533
594
}
534
595
596
+ // Extracts the name of the resource from an arn
597
+ private static extractResourceNameFromArn ( attribute : AttributeValue | undefined ) : string | undefined {
598
+ if ( typeof attribute === 'string' && attribute . startsWith ( 'arn:aws:' ) ) {
599
+ const split = attribute . split ( ':' ) ;
600
+ return split [ split . length - 1 ] ;
601
+ }
602
+
603
+ return undefined ;
604
+ }
605
+
535
606
/** Span kind is needed for differentiating metrics in the EMF exporter */
536
607
private static setSpanKindForService ( span : ReadableSpan , attributes : Attributes ) : void {
537
608
let spanKind : string = SpanKind [ span . kind ] ;
0 commit comments