Skip to content

Commit 83f5e04

Browse files
authored
Add implementation and contract tests for new AWS resources (#143)
1 parent bbda41b commit 83f5e04

File tree

14 files changed

+608
-47
lines changed

14 files changed

+608
-47
lines changed

src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsAttributeKeys.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ internal sealed class AwsAttributeKeys
4848
internal static readonly string AttributeAWSDynamoTableName = "aws.table_name";
4949
internal static readonly string AttributeAWSSQSQueueUrl = "aws.queue_url";
5050

51+
internal static readonly string AttributeAWSLambdaResourceMappingId = "aws.lambda.resource_mapping.id";
5152
internal static readonly string AttributeAWSS3Bucket = "aws.s3.bucket";
53+
internal static readonly string AttributeAWSSecretsManagerSecretArn = "aws.secretsmanager.secret.arn";
54+
internal static readonly string AttributeAWSSNSTopicArn = "aws.sns.topic.arn";
55+
internal static readonly string AttributeAWSStepFunctionsActivityArn = "aws.stepfunctions.activity.arn";
56+
internal static readonly string AttributeAWSStepFunctionsStateMachineArn = "aws.stepfunctions.state_machine.arn";
5257

5358
internal static readonly string AttributeAWSBedrockGuardrailId = "aws.bedrock.guardrail.id";
5459
internal static readonly string AttributeAWSBedrockAgentId = "aws.bedrock.agent.id";

src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ internal class AwsMetricAttributeGenerator : IMetricAttributeGenerator
4242
// Normalized remote service names for supported AWS services
4343
private static readonly string NormalizedDynamoDBServiceName = "AWS::DynamoDB";
4444
private static readonly string NormalizedKinesisServiceName = "AWS::Kinesis";
45+
private static readonly string NormalizedLambdaServiceName = "AWS::Lambda";
4546
private static readonly string NormalizedS3ServiceName = "AWS::S3";
47+
private static readonly string NormalizedSecretsManagerServiceName = "AWS::SecretsManager";
48+
private static readonly string NormalizedSNSServiceName = "AWS::SNS";
4649
private static readonly string NormalizedSQSServiceName = "AWS::SQS";
50+
private static readonly string NormalizedStepFunctionsName = "AWS::StepFunctions";
4751
private static readonly string NormalizedBedrockServiceName = "AWS::Bedrock";
4852
private static readonly string NormalizedBedrockRuntimeServiceName = "AWS::BedrockRuntime";
4953
private static readonly string DbConnectionResourceType = "DB::Connection";
@@ -358,12 +362,20 @@ private static string NormalizeRemoteServiceName(Activity span, string serviceNa
358362
case "AmazonKinesis": // AWS SDK v1
359363
case "Kinesis": // AWS SDK v2
360364
return NormalizedKinesisServiceName;
365+
case "Lambda":
366+
return NormalizedLambdaServiceName;
361367
case "Amazon S3": // AWS SDK v1
362368
case "S3": // AWS SDK v2
363369
return NormalizedS3ServiceName;
370+
case "Secrets Manager":
371+
return NormalizedSecretsManagerServiceName;
372+
case "SNS":
373+
return NormalizedSNSServiceName;
364374
case "AmazonSQS": // AWS SDK v1
365375
case "Sqs": // AWS SDK v2
366376
return NormalizedSQSServiceName;
377+
case "SFN":
378+
return NormalizedStepFunctionsName;
367379
case "Bedrock":
368380
case "Bedrock Agent":
369381
case "Bedrock Agent Runtime":
@@ -398,11 +410,28 @@ private static void SetRemoteResourceTypeAndIdentifier(Activity span, ActivityTa
398410
remoteResourceType = NormalizedKinesisServiceName + "::Stream";
399411
remoteResourceIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSKinesisStreamName));
400412
}
413+
else if (IsKeyPresent(span, AttributeAWSLambdaResourceMappingId))
414+
{
415+
remoteResourceType = NormalizedLambdaServiceName + "::EventSourceMapping";
416+
remoteResourceIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSLambdaResourceMappingId));
417+
}
401418
else if (IsKeyPresent(span, AttributeAWSS3Bucket))
402419
{
403420
remoteResourceType = NormalizedS3ServiceName + "::Bucket";
404421
remoteResourceIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSS3Bucket));
405422
}
423+
else if (IsKeyPresent(span, AttributeAWSSecretsManagerSecretArn))
424+
{
425+
remoteResourceType = NormalizedSecretsManagerServiceName + "::Secret";
426+
remoteResourceIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSSecretsManagerSecretArn))?.Split(':').Last();
427+
cloudformationPrimaryIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSSecretsManagerSecretArn));
428+
}
429+
else if (IsKeyPresent(span, AttributeAWSSNSTopicArn))
430+
{
431+
remoteResourceType = NormalizedSNSServiceName + "::Topic";
432+
remoteResourceIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSSNSTopicArn))?.Split(':').Last();
433+
cloudformationPrimaryIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSSNSTopicArn));
434+
}
406435
else if (IsKeyPresent(span, AttributeAWSSQSQueueName))
407436
{
408437
remoteResourceType = NormalizedSQSServiceName + "::Queue";
@@ -415,6 +444,18 @@ private static void SetRemoteResourceTypeAndIdentifier(Activity span, ActivityTa
415444
remoteResourceIdentifier = EscapeDelimiters(GetQueueName((string?)span.GetTagItem(AttributeAWSSQSQueueUrl)));
416445
cloudformationPrimaryIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSSQSQueueUrl));
417446
}
447+
else if (IsKeyPresent(span, AttributeAWSStepFunctionsActivityArn))
448+
{
449+
remoteResourceType = NormalizedStepFunctionsName + "::Activity";
450+
remoteResourceIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSStepFunctionsActivityArn))?.Split(':').Last();
451+
cloudformationPrimaryIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSStepFunctionsActivityArn));
452+
}
453+
else if (IsKeyPresent(span, AttributeAWSStepFunctionsStateMachineArn))
454+
{
455+
remoteResourceType = NormalizedStepFunctionsName + "::StateMachine";
456+
remoteResourceIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSStepFunctionsStateMachineArn))?.Split(':').Last();
457+
cloudformationPrimaryIdentifier = EscapeDelimiters((string?)span.GetTagItem(AttributeAWSStepFunctionsStateMachineArn));
458+
}
418459
else if (IsKeyPresent(span, AttributeAWSBedrockGuardrailId))
419460
{
420461
remoteResourceType = NormalizedBedrockServiceName + "::Guardrail";

src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ internal static class AWSSemanticConventions
1515
public const string AttributeAWSSQSQueueName = "aws.sqs.queue_name";
1616
public const string AttributeAWSS3BucketName = "aws.s3.bucket";
1717
public const string AttributeAWSKinesisStreamName = "aws.kinesis.stream_name";
18+
public const string AttributeAWSLambdaResourceMappingId = "aws.lambda.resource_mapping.id";
19+
public const string AttributeAWSSecretsManagerSecretArn = "aws.secretsmanager.secret.arn";
20+
public const string AttributeAWSSNSTopicArn = "aws.sns.topic.arn";
21+
public const string AttributeAWSStepFunctionsActivityArn = "aws.stepfunctions.activity.arn";
22+
public const string AttributeAWSStepFunctionsStateMachineArn = "aws.stepfunctions.state_machine.arn";
1823

1924
// AWS Bedrock service attributes not yet defined in semantic conventions
2025
public const string AttributeAWSBedrockGuardrailId = "aws.bedrock.guardrail.id";

src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,18 @@ internal class AWSServiceHelper
1313
{ AWSServiceType.SQSService, new List<string> { "QueueUrl", "QueueName" } },
1414
{ AWSServiceType.S3Service, new List<string> { "BucketName" } },
1515
{ AWSServiceType.KinesisService, new List<string> { "StreamName" } },
16+
{ AWSServiceType.LambdaService, new List<string> { "UUID" } },
17+
{ AWSServiceType.SecretsManagerService, new List<string> { "SecretId" } },
18+
{ AWSServiceType.SNSService, new List<string> { "TopicArn" } },
19+
{ AWSServiceType.StepFunctionsService, new List<string> { "ActivityArn", "StateMachineArn" } },
1620
{ AWSServiceType.BedrockRuntimeService, new List<string> { "ModelId" } },
1721
{ AWSServiceType.BedrockAgentService, new List<string> { "AgentId", "KnowledgeBaseId", "DataSourceId" } },
1822
{ AWSServiceType.BedrockAgentRuntimeService, new List<string> { "AgentId", "KnowledgeBaseId" } },
1923
};
2024

2125
internal static IReadOnlyDictionary<string, List<string>> ServiceResponseParameterMap = new Dictionary<string, List<string>>()
2226
{
27+
{ AWSServiceType.SecretsManagerService, new List<string> { "ARN" } },
2328
{ AWSServiceType.SQSService, new List<string> { "QueueUrl" } },
2429
{ AWSServiceType.BedrockService, new List<string> { "GuardrailId" } },
2530
{ AWSServiceType.BedrockAgentService, new List<string> { "AgentId", "DataSourceId" } },
@@ -32,6 +37,12 @@ internal class AWSServiceHelper
3237
{ "QueueName", AWSSemanticConventions.AttributeAWSSQSQueueName },
3338
{ "BucketName", AWSSemanticConventions.AttributeAWSS3BucketName },
3439
{ "StreamName", AWSSemanticConventions.AttributeAWSKinesisStreamName },
40+
{ "TopicArn", AWSSemanticConventions.AttributeAWSSNSTopicArn },
41+
{ "ARN", AWSSemanticConventions.AttributeAWSSecretsManagerSecretArn },
42+
{ "SecretId", AWSSemanticConventions.AttributeAWSSecretsManagerSecretArn },
43+
{ "ActivityArn", AWSSemanticConventions.AttributeAWSStepFunctionsActivityArn },
44+
{ "StateMachineArn", AWSSemanticConventions.AttributeAWSStepFunctionsStateMachineArn },
45+
{ "UUID", AWSSemanticConventions.AttributeAWSLambdaResourceMappingId },
3546
{ "ModelId", AWSSemanticConventions.AttributeGenAiModelId },
3647
{ "GuardrailId", AWSSemanticConventions.AttributeAWSBedrockGuardrailId },
3748
{ "AgentId", AWSSemanticConventions.AttributeAWSBedrockAgentId },

src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ internal class AWSServiceType
1010
internal const string SNSService = "SNS";
1111
internal const string S3Service = "S3";
1212
internal const string KinesisService = "Kinesis";
13+
internal const string LambdaService = "Lambda";
14+
internal const string SecretsManagerService = "Secrets Manager";
15+
internal const string StepFunctionsService = "SFN";
1316
internal const string BedrockService = "Bedrock";
1417
internal const string BedrockRuntimeService = "Bedrock Runtime";
1518
internal const string BedrockAgentService = "Bedrock Agent";
@@ -27,9 +30,18 @@ internal static bool IsSnsService(string service)
2730
internal static bool IsS3Service(string service)
2831
=> S3Service.Equals(service, StringComparison.OrdinalIgnoreCase);
2932

33+
internal static bool IsLambdaService(string service)
34+
=> LambdaService.Equals(service, StringComparison.OrdinalIgnoreCase);
35+
3036
internal static bool IsKinesisService(string service)
3137
=> KinesisService.Equals(service, StringComparison.OrdinalIgnoreCase);
3238

39+
internal static bool IsSecretsManagerService(string service)
40+
=> SecretsManagerService.Equals(service, StringComparison.OrdinalIgnoreCase);
41+
42+
internal static bool IsStepFunctionsService(string service)
43+
=> StepFunctionsService.Equals(service, StringComparison.OrdinalIgnoreCase);
44+
3345
internal static bool IsBedrockService(string service)
3446
=> BedrockService.Equals(service, StringComparison.OrdinalIgnoreCase);
3547

src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,20 @@ private static void AddRequestSpecificInformation(Activity activity, IRequestCon
164164
}
165165
}
166166

167+
// for secrets manager, only extract SecretId from request if it is a secret ARN.
168+
if (AWSServiceType.IsSecretsManagerService(service) && parameter == "SecretId")
169+
{
170+
var secretId = property.GetValue(request);
171+
if (secretId != null)
172+
{
173+
var secretIdString = secretId.ToString();
174+
if (secretIdString != null && !secretIdString.StartsWith("arn:aws:secretsmanager:"))
175+
{
176+
continue;
177+
}
178+
}
179+
}
180+
167181
if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute))
168182
{
169183
activity.SetTag(attribute, property.GetValue(request));

0 commit comments

Comments
 (0)