From 5ced5776ae74640a68c17ac8f57def27b3942954 Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 17:17:56 -0700 Subject: [PATCH 01/13] fix: resolve nullable warnings and enforce TreatWarningsAsErrors - Fix nullable type spacing and null literal warnings - Configure build to fail on warnings to prevent future issues --- build/Build.cs | 3 ++- .../RegionalResourceArnParser.cs | 2 +- .../AwsMetricAttributesGeneratorTest.cs | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/build/Build.cs b/build/Build.cs index 6fbbc8dc..98b046e8 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -206,7 +206,8 @@ Copyright The OpenTelemetry Authors under Apache License Version 2.0 DotNetBuild(s => s .SetProjectFile(project) .SetNoRestore(true) - .SetConfiguration(this.configuration)); + .SetConfiguration(this.configuration) + .SetProperty("TreatWarningsAsErrors", "true")); } }); diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/RegionalResourceArnParser.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/RegionalResourceArnParser.cs index bcc9146c..f9385bdc 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/RegionalResourceArnParser.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/RegionalResourceArnParser.cs @@ -23,7 +23,7 @@ public class RegionalResourceArnParser /// arn:partition:service:region:account-id:resource-type/resource-id or /// arn:partition:service:region:account-id:resource-type:resource-id /// - private static string[] ? ParseArn(string? arn) + private static string[]? ParseArn(string? arn) { if (arn == null || !arn.StartsWith("arn:")) { diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsMetricAttributesGeneratorTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsMetricAttributesGeneratorTest.cs index 77edef6e..3e8f07f5 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsMetricAttributesGeneratorTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsMetricAttributesGeneratorTest.cs @@ -1147,7 +1147,7 @@ public void TestSdkClientSpanWithRemoteResourceAttributes() { { AttributeAWSSNSTopicArn, "arn:aws:sns:us-west-2:invalid_account_id:aws_topic_arn" }, }; - this.ValidateRemoteResourceAttributes(attributesCombination, null, null, null); + this.ValidateRemoteResourceAttributes(attributesCombination, null!, null!, null!); // Arn with invalid region attributesCombination = new Dictionary @@ -1161,7 +1161,7 @@ public void TestSdkClientSpanWithRemoteResourceAttributes() { { AttributeAWSSNSTopicArn, "invalid_arn" }, }; - this.ValidateRemoteResourceAttributes(attributesCombination, null, null, null); + this.ValidateRemoteResourceAttributes(attributesCombination, null!, null!, null!); // Invalid arn but account access key is available attributesCombination = new Dictionary @@ -1170,7 +1170,7 @@ public void TestSdkClientSpanWithRemoteResourceAttributes() { AttributeAWSAuthAccessKey, this.awsRemoteResourceAccessKey }, { AttributeAWSAuthRegion, this.awsRemoteResourceRegion }, }; - this.ValidateRemoteResourceAttributes(attributesCombination, null, null, null); + this.ValidateRemoteResourceAttributes(attributesCombination, null!, null!, null!); } [Fact] From f6457c562e8b57428a2d7ede3edeba0be719af5a Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 17:30:47 -0700 Subject: [PATCH 02/13] Use same version of StyleCop.Analyzers as upstream --- .../AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj index 4e8e7053..39a0cee5 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj @@ -33,7 +33,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 704b7ef5f5a050e039f02b9d4b6d94d0e2aa32df Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 20:05:29 -0700 Subject: [PATCH 03/13] fix: resolve StyleCop analyzer errors and improve code compliance - Enable XML documentation generation to fix SA0001 error - Add missing newlines at end of files (SA1518) - Remove space after 'new' keyword (SA1000) - Add tuple element names and fix casing (SA1414, SA1316) - Fix tuple element references in SqlUrlParser methods --- .../AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj | 1 + .../AWSOpenTelemetryOptions.cs | 2 +- .../AWSXRayEventSource.cs | 2 +- .../AwsBatchUnsampledSpanExportProcessor.cs | 2 +- .../LambdaWrapper.cs | 4 ++-- .../SqlUrlParser.cs | 6 +++--- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj index 39a0cee5..c11c31f4 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj @@ -8,6 +8,7 @@ enable true ../../buildtools/awsoteldotnet.snk + true diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSOpenTelemetryOptions.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSOpenTelemetryOptions.cs index c1376a25..4d1c3108 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSOpenTelemetryOptions.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSOpenTelemetryOptions.cs @@ -22,4 +22,4 @@ internal AWSOpenTelemetryOptions(IConfiguration configuration) { // custom implementation of initializing exporter settings / instrumentations / Service Name etc. } -} \ No newline at end of file +} diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSXRayEventSource.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSXRayEventSource.cs index 78fbbe05..7431bbbf 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSXRayEventSource.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSXRayEventSource.cs @@ -9,7 +9,7 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation; [EventSource(Name = "OpenTelemetry-AWS-XRay")] internal class AWSXRayEventSource : EventSource { - internal static readonly AWSXRayEventSource Log = new (); + internal static readonly AWSXRayEventSource Log = new(); [NonEvent] public void ActivityContextExtractException(string format, Exception ex) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsBatchUnsampledSpanExportProcessor.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsBatchUnsampledSpanExportProcessor.cs index 08bdd192..1b72b5a8 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsBatchUnsampledSpanExportProcessor.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsBatchUnsampledSpanExportProcessor.cs @@ -42,4 +42,4 @@ public override void OnEnd(Activity data) this.OnExport(data); } } -} \ No newline at end of file +} diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs index 252d93c0..2c1b11d5 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs @@ -154,7 +154,7 @@ static LambdaWrapper() } } - private (MethodInfo, object) ExtractOriginalHandler() + private (MethodInfo handlerMethod, object handlerInstance) ExtractOriginalHandler() { string? originalHandler = Environment.GetEnvironmentVariable("OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER"); if (string.IsNullOrEmpty(originalHandler)) @@ -188,4 +188,4 @@ static LambdaWrapper() return (handlerMethod, handlerInstance); } } -#endif \ No newline at end of file +#endif diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqlUrlParser.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqlUrlParser.cs index fdecb6fb..3b664b21 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqlUrlParser.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqlUrlParser.cs @@ -40,16 +40,16 @@ public class SqsUrlParser return null; } - public static string? GetAccountId(string? url) => ParseUrl(url).accountId; + public static string? GetAccountId(string? url) => ParseUrl(url).AccountId; - public static string? GetRegion(string? url) => ParseUrl(url).region; + public static string? GetRegion(string? url) => ParseUrl(url).Region; /// /// Parses new SQS URLs https://sqs.region.amazonaws.com/accountI/queueName; /// /// SQS URL to parse /// Tuple containing queue name, account ID, and region - public static (string? QueueName, string? accountId, string? region) ParseUrl(string? url) + public static (string? QueueName, string? AccountId, string? Region) ParseUrl(string? url) { if (url == null) { From ef4949b326a410a0c56f3fabc18d2611e877614a Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 20:29:40 -0700 Subject: [PATCH 04/13] fix: resolve StyleCop analyzer errors and improve XML documentation - Remove empty AWSDistroOpenTelemetryEventSource.cs file (https://github.com/aws-observability/aws-otel-dotnet-instrumentation/pull/16#discussion_r1610844464) - Fix malformed XML documentation in AlwaysRecordSampler.cs - Fix XML documentation formatting in AwsMetricAttributeGenerator.cs with proper closing tags - Update tuple element casing and variable references in LambdaWrapper.cs - Add comprehensive XML documentation to RegionalResourceArnParser.cs - Renamed MetricAttributeGenerator.cs -> IMetricAttributeGenerator.cs and SqlUrlParser.cs -> SqsUrlParser.cs --- .../AWSDistroOpenTelemetryEventSource.cs | 0 .../AlwaysRecordSampler.cs | 6 ++-- .../AwsMetricAttributeGenerator.cs | 22 +++++++-------- ...erator.cs => IMetricAttributeGenerator.cs} | 0 .../LambdaWrapper.cs | 16 +++++------ .../RegionalResourceArnParser.cs | 28 +++++++++++++++++++ .../{SqlUrlParser.cs => SqsUrlParser.cs} | 10 +++++++ 7 files changed, 60 insertions(+), 22 deletions(-) delete mode 100644 src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSDistroOpenTelemetryEventSource.cs rename src/AWS.Distro.OpenTelemetry.AutoInstrumentation/{MetricAttributeGenerator.cs => IMetricAttributeGenerator.cs} (100%) rename src/AWS.Distro.OpenTelemetry.AutoInstrumentation/{SqlUrlParser.cs => SqsUrlParser.cs} (89%) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSDistroOpenTelemetryEventSource.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWSDistroOpenTelemetryEventSource.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AlwaysRecordSampler.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AlwaysRecordSampler.cs index 48b3a4a0..e8d4ccfa 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AlwaysRecordSampler.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AlwaysRecordSampler.cs @@ -6,13 +6,13 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation; /// -/// This sampler will return the sampling result of the provided {@link #rootSampler}, unless the +/// This sampler will return the sampling result of the provided rootSampler, unless the /// sampling result contains the sampling decision , in which case, a /// new sampling result will be returned that is functionally equivalent to the original, except that /// it contains the sampling decision . This ensures that all /// spans are recorded, with no change to sampling. -/// -///

The intended use case of this sampler is to provide a means of sending all spans to a +/// +/// The intended use case of this sampler is to provide a means of sending all spans to a /// processor without having an impact on the sampling rate. This may be desirable if a user wishes /// to count or otherwise measure all spans produced in a service, without incurring the cost of 100% /// sampling. diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs index 683933dd..64155cf7 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs @@ -169,28 +169,28 @@ private static void SetEgressOperation(Activity span, ActivityTagsCollection att /// instrumented span attributes, and are clear indications of customer intent. If AWS Remote /// attributes are not present, the next highest priority span attribute is Peer Service, which is /// also a reliable indicator of customer intent. If this is set, it will override - /// AWS_REMOTE_SERVICE identified from any other span attribute, other than AWS Remote attributes. + /// AWS_REMOTE_SERVICE identified from any other span attribute, other than AWS Remote attributes.

/// ///

After this, we look for the following low-cardinality span attributes that can be used to - /// determine the remote metric attributes: + /// determine the remote metric attributes:

/// ///
    - ///
  • RPC - ///
  • DB - ///
  • FAAS - ///
  • Messaging + ///
  • RPC
  • + ///
  • DB
  • + ///
  • FAAS
  • + ///
  • Messaging
  • ///
  • GraphQL - Special case, if is present, - /// we use it for RemoteOperation and set RemoteService to . + /// we use it for RemoteOperation and set RemoteService to .
  • ///
/// ///

In each case, these span attributes were selected from the OpenTelemetry trace semantic - /// convention specifications as they adhere to the three following criteria: + /// convention specifications as they adhere to the three following criteria:

/// ///
    - ///
  • Attributes are meaningfully indicative of remote service/operation names. + ///
  • Attributes are meaningfully indicative of remote service/operation names.
  • ///
  • Attributes are defined in the specification to be low cardinality, usually with a low- - /// cardinality list of values. - ///
  • Attributes are confirmed to have low-cardinality values, based on code analysis. + /// cardinality list of values.
  • + ///
  • Attributes are confirmed to have low-cardinality values, based on code analysis.
  • ///
/// /// if the selected attributes are still producing the UnknownRemoteService or diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/MetricAttributeGenerator.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/IMetricAttributeGenerator.cs similarity index 100% rename from src/AWS.Distro.OpenTelemetry.AutoInstrumentation/MetricAttributeGenerator.cs rename to src/AWS.Distro.OpenTelemetry.AutoInstrumentation/IMetricAttributeGenerator.cs diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs index 2c1b11d5..85f012a7 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs @@ -63,7 +63,7 @@ static LambdaWrapper() /// The following are assumptions made about the lambda handler function parameters. /// * Maximum Parameters: A .NET Lambda handler function can have up to two parameters. /// * Parameter Order: If both parameters are used, the event input parameter must come first, followed by the ILambdaContext. - /// * Return Types: The handler can return void, a specific type, or a Task/Task for asynchronous methods. + /// * Return Types: The handler can return void, a specific type, or a Task/Task[T] for asynchronous methods. ///
/// /// @@ -77,10 +77,10 @@ static LambdaWrapper() throw new Exception($"Input cannot be null."); } - (MethodInfo handlerMethod, object handlerInstance) = this.ExtractOriginalHandler(); + (MethodInfo HandlerMethod, object HandlerInstance) = this.ExtractOriginalHandler(); object? originalHandlerResult; - ParameterInfo[] parameters = handlerMethod.GetParameters(); + ParameterInfo[] parameters = HandlerMethod.GetParameters(); // A .NET Lambda handler function can have zero, one, or two parameters, depending on the customer's needs: // * Zero Parameters: When no input data or context is needed. @@ -96,7 +96,7 @@ static LambdaWrapper() throw new Exception($"Wrapper wasn't able to convert the input object to type: {inputParameterType}!"); } - originalHandlerResult = handlerMethod.Invoke(handlerInstance, new object[] { inputObject, context }); + originalHandlerResult = HandlerMethod.Invoke(HandlerInstance, new object[] { inputObject, context }); } else if (parameters.Length == 1) { @@ -108,18 +108,18 @@ static LambdaWrapper() throw new Exception($"Wrapper wasn't able to convert the input object to type: {inputParameterType}!"); } - originalHandlerResult = handlerMethod.Invoke(handlerInstance, new object[] { inputObject }); + originalHandlerResult = HandlerMethod.Invoke(HandlerInstance, new object[] { inputObject }); } else if (parameters.Length == 0) { - originalHandlerResult = handlerMethod.Invoke(handlerInstance, new object[] { }); + originalHandlerResult = HandlerMethod.Invoke(HandlerInstance, new object[] { }); } else { throw new Exception($"Wrapper handler doesn't support more than 2 input paramaters"); } - Type returnType = handlerMethod.ReturnType; + Type returnType = HandlerMethod.ReturnType; if (originalHandlerResult == null && returnType.ToString() != typeof(void).ToString()) { throw new Exception($"originalHandlerResult of type: {returnType} returned from the original handler is null!"); @@ -128,7 +128,7 @@ static LambdaWrapper() // AsyncStateMachineAttribute can be used to determine whether the original handler method is // asynchronous vs synchronous Type asyncAttribType = typeof(AsyncStateMachineAttribute); - var asyncAttrib = (AsyncStateMachineAttribute?)handlerMethod.GetCustomAttribute(asyncAttribType); + var asyncAttrib = (AsyncStateMachineAttribute?)HandlerMethod.GetCustomAttribute(asyncAttribType); // The return type of the original lambda function is Task or Task so we await for it if (asyncAttrib != null && originalHandlerResult != null) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/RegionalResourceArnParser.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/RegionalResourceArnParser.cs index f9385bdc..e94a3215 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/RegionalResourceArnParser.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/RegionalResourceArnParser.cs @@ -3,18 +3,46 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation; +/// +/// Parser for AWS regional resource ARNs. +/// public class RegionalResourceArnParser { + /// + /// Gets the account ID from an AWS ARN. + /// + /// The ARN to parse. + /// The account ID or null if not found. public static string? GetAccountId(string? arn) => ParseArn(arn)?[4]; + /// + /// Gets the region from an AWS ARN. + /// + /// The ARN to parse. + /// The region or null if not found. public static string? GetRegion(string? arn) => ParseArn(arn)?[3]; + /// + /// Extracts the Kinesis stream name from an ARN. + /// + /// The Kinesis stream ARN. + /// The stream name or null if not found. public static string? ExtractKinesisStreamNameFromArn(string? arn) => ExtractResourceNameFromArn(arn)?.Replace("stream/", string.Empty); + /// + /// Extracts the DynamoDB table name from an ARN. + /// + /// The DynamoDB table ARN. + /// The table name or null if not found. public static string? ExtractDynamoDbTableNameFromArn(string? arn) => ExtractResourceNameFromArn(arn)?.Replace("table/", string.Empty); + /// + /// Extracts the resource name from an AWS ARN. + /// + /// The ARN to parse. + /// The resource name or null if not found. public static string? ExtractResourceNameFromArn(string? arn) => ParseArn(arn) is var parts && parts != null ? parts[parts.Length - 1] : null; diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqlUrlParser.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqsUrlParser.cs similarity index 89% rename from src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqlUrlParser.cs rename to src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqsUrlParser.cs index 3b664b21..b35bf972 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqlUrlParser.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/SqsUrlParser.cs @@ -40,8 +40,18 @@ public class SqsUrlParser return null; } + /// + /// Gets the account ID from an SQS URL. + /// + /// The SQS URL to parse. + /// The account ID or null if not found. public static string? GetAccountId(string? url) => ParseUrl(url).AccountId; + /// + /// Gets the region from an SQS URL. + /// + /// The SQS URL to parse. + /// The region or null if not found. public static string? GetRegion(string? url) => ParseUrl(url).Region; /// From 3599dd73a721f408b957149343d323919e97aed6 Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 20:35:23 -0700 Subject: [PATCH 05/13] fix: resolve StyleCop analyzer errors and improve XML documentation - Fix XML documentation formatting in AlwaysRecordSampler.cs by removing

tags - Fix XML documentation in AwsMetricAttributeGenerator.cs by removing malformed

tags and fixing braces - Update tuple element casing in LambdaWrapper.cs ExtractOriginalHandler method - Standardize variable naming to match tuple element names (HandlerMethod, HandlerInstance) --- .../AlwaysRecordSampler.cs | 2 +- .../AwsMetricAttributeGenerator.cs | 4 ++-- .../LambdaWrapper.cs | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AlwaysRecordSampler.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AlwaysRecordSampler.cs index e8d4ccfa..c52ea348 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AlwaysRecordSampler.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AlwaysRecordSampler.cs @@ -11,7 +11,7 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation; /// new sampling result will be returned that is functionally equivalent to the original, except that /// it contains the sampling decision . This ensures that all /// spans are recorded, with no change to sampling. -/// +/// /// The intended use case of this sampler is to provide a means of sending all spans to a /// processor without having an impact on the sampling rate. This may be desirable if a user wishes /// to count or otherwise measure all spans produced in a service, without incurring the cost of 100% diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs index 64155cf7..31a0dcc6 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributeGenerator.cs @@ -18,9 +18,9 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation; ///

/// AwsMetricAttributeGenerator generates very specific metric attributes based on low-cardinality /// span and resource attributes. If such attributes are not present, we fallback to default values. -///

The goal of these particular metric attributes is to get metrics for incoming and outgoing +/// The goal of these particular metric attributes is to get metrics for incoming and outgoing /// traffic for a service. Namely, and spans -/// represent "incoming" traffic, { and spans +/// represent "incoming" traffic, and spans /// represent "outgoing" traffic, and spans are ignored. ///

internal class AwsMetricAttributeGenerator : IMetricAttributeGenerator diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs index 85f012a7..36f821ec 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs @@ -154,7 +154,7 @@ static LambdaWrapper() } } - private (MethodInfo handlerMethod, object handlerInstance) ExtractOriginalHandler() + private (MethodInfo HandlerMethod, object HandlerInstance) ExtractOriginalHandler() { string? originalHandler = Environment.GetEnvironmentVariable("OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER"); if (string.IsNullOrEmpty(originalHandler)) @@ -173,19 +173,19 @@ static LambdaWrapper() throw new Exception($"handlerType of type: ${type} and assembly: ${assembly} was not found"); } - object? handlerInstance = Activator.CreateInstance(handlerType); - if (handlerInstance == null) + object? HandlerInstance = Activator.CreateInstance(handlerType); + if (HandlerInstance == null) { - throw new Exception("handlerInstance was not created"); + throw new Exception("HandlerInstance was not created"); } - MethodInfo? handlerMethod = handlerType.GetMethod(method); - if (handlerMethod == null) + MethodInfo? HandlerMethod = handlerType.GetMethod(method); + if (HandlerMethod == null) { - throw new Exception($"handlerMethod: ${method} was not found"); + throw new Exception($"HandlerMethod: ${method} was not found"); } - return (handlerMethod, handlerInstance); + return (HandlerMethod, HandlerInstance); } } #endif From 3e88493fa1108d0d1769f83c504bb23b5288fc5c Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 20:43:49 -0700 Subject: [PATCH 06/13] more checkstlye issues --- ...ttributePropagatingSpanProcessorBuilder.cs | 23 +++++++++++++ .../AwsMetricAttributesSpanProcessor.cs | 18 +++++----- .../IMetricAttributeGenerator.cs | 2 +- .../LambdaWrapper.cs | 34 +++++++++---------- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AttributePropagatingSpanProcessorBuilder.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AttributePropagatingSpanProcessorBuilder.cs index 66159b6e..f6815970 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AttributePropagatingSpanProcessorBuilder.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AttributePropagatingSpanProcessorBuilder.cs @@ -25,11 +25,20 @@ private AttributePropagatingSpanProcessorBuilder() { } + /// + /// Creates a new AttributePropagatingSpanProcessorBuilder instance. + /// + /// A new builder instance. public static AttributePropagatingSpanProcessorBuilder Create() { return new AttributePropagatingSpanProcessorBuilder(); } + /// + /// Sets the propagation data extractor function. + /// + /// Function to extract propagation data from activity. + /// This builder instance. public AttributePropagatingSpanProcessorBuilder SetPropagationDataExtractor(Func propagationDataExtractor) { if (propagationDataExtractor == null) @@ -41,6 +50,11 @@ public AttributePropagatingSpanProcessorBuilder SetPropagationDataExtractor(Func return this; } + /// + /// Sets the propagation data key. + /// + /// The key for propagation data. + /// This builder instance. public AttributePropagatingSpanProcessorBuilder SetPropagationDataKey(string propagationDataKey) { if (propagationDataKey == null) @@ -52,6 +66,11 @@ public AttributePropagatingSpanProcessorBuilder SetPropagationDataKey(string pro return this; } + /// + /// Sets the attribute keys to propagate. + /// + /// List of attribute keys to propagate. + /// This builder instance. public AttributePropagatingSpanProcessorBuilder SetAttributesKeysToPropagate(List attributesKeysToPropagate) { if (attributesKeysToPropagate == null) @@ -64,6 +83,10 @@ public AttributePropagatingSpanProcessorBuilder SetAttributesKeysToPropagate(Lis return this; } + /// + /// Builds the AttributePropagatingSpanProcessor. + /// + /// The configured processor. public AttributePropagatingSpanProcessor Build() { return AttributePropagatingSpanProcessor diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributesSpanProcessor.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributesSpanProcessor.cs index fff56337..e9cc7817 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributesSpanProcessor.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsMetricAttributesSpanProcessor.cs @@ -78,16 +78,18 @@ private static Activity WrapSpanWithAttributes(Activity span, ActivityTagsCollec return span; } + /// + /// If the map has no items, no modifications are required. If there is one item, it means the + /// span either produces Service or Dependency metric attributes, and in either case we want to + /// modify the span with them. If there are two items, the span produces both Service and + /// Dependency metric attributes indicating the span is a local dependency root. The Service + /// Attributes must be a subset of the Dependency, with the exception of AttributeAWSSpanKind. The + /// knowledge that the span is a local root is more important that knowing that it is a + /// Dependency metric, so we take all the Dependency metrics but replace AttributeAWSSpanKind with + /// . + /// private Activity AddMetricAttributes(Activity span) { - /// If the map has no items, no modifications are required. If there is one item, it means the - /// span either produces Service or Dependency metric attributes, and in either case we want to - /// modify the span with them. If there are two items, the span produces both Service and - /// Dependency metric attributes indicating the span is a local dependency root. The Service - /// Attributes must be a subset of the Dependency, with the exception of AttributeAWSSpanKind. The - /// knowledge that the span is a local root is more important that knowing that it is a - /// Dependency metric, so we take all the Dependency metrics but replace AttributeAWSSpanKind with - /// . Dictionary attributeMap = this.generator.GenerateMetricAttributeMapFromSpan(span, this.resource); ActivityTagsCollection attributes = new ActivityTagsCollection(); diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/IMetricAttributeGenerator.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/IMetricAttributeGenerator.cs index 9d8c543c..7f00ca2c 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/IMetricAttributeGenerator.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/IMetricAttributeGenerator.cs @@ -10,7 +10,7 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation; /// /// Metric attribute generator defines an interface for classes that can generate specific attributes /// to be used by an to produce metrics and by -/// to wrap the original span. +/// AwsMetricAttributesSpanExporter to wrap the original span. /// public interface IMetricAttributeGenerator { diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs index 36f821ec..e639ff20 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/LambdaWrapper.cs @@ -65,9 +65,9 @@ static LambdaWrapper() /// * Parameter Order: If both parameters are used, the event input parameter must come first, followed by the ILambdaContext. /// * Return Types: The handler can return void, a specific type, or a Task/Task[T] for asynchronous methods. ///
- /// - /// - /// + /// Input JObject to be converted to the correct object type. + /// Lambda context for the function execution. + /// Task containing the result object from the original handler. /// Multiple exceptions that act as safe gaurds in case any of the /// assumptions are wrong or if for any reason reflection is failing to get the original function and it's info. private async Task FunctionHandler(JObject input, ILambdaContext context) @@ -77,10 +77,10 @@ static LambdaWrapper() throw new Exception($"Input cannot be null."); } - (MethodInfo HandlerMethod, object HandlerInstance) = this.ExtractOriginalHandler(); + (MethodInfo handlerMethod, object handlerInstance) = this.ExtractOriginalHandler(); object? originalHandlerResult; - ParameterInfo[] parameters = HandlerMethod.GetParameters(); + ParameterInfo[] parameters = handlerMethod.GetParameters(); // A .NET Lambda handler function can have zero, one, or two parameters, depending on the customer's needs: // * Zero Parameters: When no input data or context is needed. @@ -96,7 +96,7 @@ static LambdaWrapper() throw new Exception($"Wrapper wasn't able to convert the input object to type: {inputParameterType}!"); } - originalHandlerResult = HandlerMethod.Invoke(HandlerInstance, new object[] { inputObject, context }); + originalHandlerResult = handlerMethod.Invoke(handlerInstance, new object[] { inputObject, context }); } else if (parameters.Length == 1) { @@ -108,18 +108,18 @@ static LambdaWrapper() throw new Exception($"Wrapper wasn't able to convert the input object to type: {inputParameterType}!"); } - originalHandlerResult = HandlerMethod.Invoke(HandlerInstance, new object[] { inputObject }); + originalHandlerResult = handlerMethod.Invoke(handlerInstance, new object[] { inputObject }); } else if (parameters.Length == 0) { - originalHandlerResult = HandlerMethod.Invoke(HandlerInstance, new object[] { }); + originalHandlerResult = handlerMethod.Invoke(handlerInstance, new object[] { }); } else { throw new Exception($"Wrapper handler doesn't support more than 2 input paramaters"); } - Type returnType = HandlerMethod.ReturnType; + Type returnType = handlerMethod.ReturnType; if (originalHandlerResult == null && returnType.ToString() != typeof(void).ToString()) { throw new Exception($"originalHandlerResult of type: {returnType} returned from the original handler is null!"); @@ -128,7 +128,7 @@ static LambdaWrapper() // AsyncStateMachineAttribute can be used to determine whether the original handler method is // asynchronous vs synchronous Type asyncAttribType = typeof(AsyncStateMachineAttribute); - var asyncAttrib = (AsyncStateMachineAttribute?)HandlerMethod.GetCustomAttribute(asyncAttribType); + var asyncAttrib = (AsyncStateMachineAttribute?)handlerMethod.GetCustomAttribute(asyncAttribType); // The return type of the original lambda function is Task or Task so we await for it if (asyncAttrib != null && originalHandlerResult != null) @@ -173,19 +173,19 @@ static LambdaWrapper() throw new Exception($"handlerType of type: ${type} and assembly: ${assembly} was not found"); } - object? HandlerInstance = Activator.CreateInstance(handlerType); - if (HandlerInstance == null) + object? handlerInstance = Activator.CreateInstance(handlerType); + if (handlerInstance == null) { - throw new Exception("HandlerInstance was not created"); + throw new Exception("handlerInstance was not created"); } - MethodInfo? HandlerMethod = handlerType.GetMethod(method); - if (HandlerMethod == null) + MethodInfo? handlerMethod = handlerType.GetMethod(method); + if (handlerMethod == null) { - throw new Exception($"HandlerMethod: ${method} was not found"); + throw new Exception($"handlerMethod: ${method} was not found"); } - return (HandlerMethod, HandlerInstance); + return (handlerMethod, handlerInstance); } } #endif From 497c56a6bfcc02467f041b4855c0e4a123cac78e Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 20:47:58 -0700 Subject: [PATCH 07/13] last fix? --- .../integration-test-app/integration-test-app.csproj | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sample-applications/integration-test-app/integration-test-app/integration-test-app.csproj b/sample-applications/integration-test-app/integration-test-app/integration-test-app.csproj index 57556212..93e292a2 100644 --- a/sample-applications/integration-test-app/integration-test-app/integration-test-app.csproj +++ b/sample-applications/integration-test-app/integration-test-app/integration-test-app.csproj @@ -3,11 +3,15 @@ netcoreapp8.0 integration_test_app + + $(NoWarn);SA0001;SA1300 - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 33eb1d17f8b1486f0817a64b613aa348db7053f5 Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 20:53:03 -0700 Subject: [PATCH 08/13] Fix tests chceckstyle --- ...WS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj index 8df3283e..766c5827 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj @@ -8,6 +8,10 @@ ../../buildtools/awsoteldotnet.snk false true + + $(NoWarn);SA0001;SA1300
@@ -27,7 +31,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From e16f6b851722cd111faf49875dbeec9e04039099 Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 21:07:37 -0700 Subject: [PATCH 09/13] more fixes --- .../AwsMetricAttributesGeneratorTest.cs | 160 +++++++++--------- .../AwsSpanMetricsProcessorTest.cs | 42 ++--- .../OtlpAwsSpanExporterTest.cs | 41 ++--- .../RegionalResourceArnParserTest.cs | 2 +- 4 files changed, 124 insertions(+), 121 deletions(-) diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsMetricAttributesGeneratorTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsMetricAttributesGeneratorTest.cs index 3e8f07f5..8ab2e2f1 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsMetricAttributesGeneratorTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsMetricAttributesGeneratorTest.cs @@ -55,9 +55,9 @@ public void TestServerSpanWithoutAttributes() { List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), - new (AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), + new(AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), + new(AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Server); @@ -70,11 +70,11 @@ public void TestConsumerSpanWithoutAttributes() { List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Consumer.ToString().ToUpper()), - new (AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), - new (AttributeAWSRemoteService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteService), - new (AttributeAWSRemoteOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteOperation), + new(AttributeAWSSpanKind, ActivityKind.Consumer.ToString().ToUpper()), + new(AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), + new(AttributeAWSRemoteService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteService), + new(AttributeAWSRemoteOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Consumer); @@ -88,9 +88,9 @@ public void TestSpanAttributesForEmptyResource() this.resource = Resource.Empty; List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), - new (AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), + new(AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), + new(AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Server); @@ -103,11 +103,11 @@ public void TestProducerSpanWithoutAttributes() { List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Producer.ToString().ToUpper()), - new (AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), - new (AttributeAWSRemoteService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteService), - new (AttributeAWSRemoteOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteOperation), + new(AttributeAWSSpanKind, ActivityKind.Producer.ToString().ToUpper()), + new(AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), + new(AttributeAWSRemoteService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteService), + new(AttributeAWSRemoteOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Producer); @@ -120,11 +120,11 @@ public void TestClientSpanWithoutAttributes() { List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Client.ToString().ToUpper()), - new (AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), - new (AttributeAWSRemoteService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteService), - new (AttributeAWSRemoteOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteOperation), + new(AttributeAWSSpanKind, ActivityKind.Client.ToString().ToUpper()), + new(AttributeAWSLocalService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownService), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), + new(AttributeAWSRemoteService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteService), + new(AttributeAWSRemoteOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Client); @@ -149,9 +149,9 @@ public void TestLocalRootServerSpan() Activity? spanDataMock = this.testSource.StartActivity(this.spanNameValue, ActivityKind.Server); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, this.spanNameValue), + new(AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, this.spanNameValue), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); this.ValidateAttributesProducedForNonLocalRootSpanOfKind(expectedAttributes, spanDataMock); @@ -165,9 +165,9 @@ public void TestLocalRootInternalSpan() Activity? spanDataMock = this.testSource.StartActivity(this.spanNameValue, ActivityKind.Internal); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), + new(AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); this.ValidateAttributesProducedForNonLocalRootSpanOfKind(expectedAttributes, spanDataMock); @@ -184,18 +184,18 @@ public void TestLocalRootClientSpan() List> expectServiceAttiributesList = new List> { - new (AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), + new(AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), }; List> expectDependencyAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Client.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), - new (AttributeAWSRemoteService, this.awsRemoteServiceValue), - new (AttributeAWSRemoteOperation, this.awsRemoteOperationValue), + new(AttributeAWSSpanKind, ActivityKind.Client.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), + new(AttributeAWSRemoteService, this.awsRemoteServiceValue), + new(AttributeAWSRemoteOperation, this.awsRemoteOperationValue), }; ActivityTagsCollection expectServiceAttiributes = new ActivityTagsCollection(expectServiceAttiributesList); @@ -215,18 +215,18 @@ public void TestLocalRootConsumerSpan() List> expectServiceAttiributesList = new List> { - new (AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), + new(AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), }; List> expectDependencyAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Consumer.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), - new (AttributeAWSRemoteService, this.awsRemoteServiceValue), - new (AttributeAWSRemoteOperation, this.awsRemoteOperationValue), + new(AttributeAWSSpanKind, ActivityKind.Consumer.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), + new(AttributeAWSRemoteService, this.awsRemoteServiceValue), + new(AttributeAWSRemoteOperation, this.awsRemoteOperationValue), }; ActivityTagsCollection expectServiceAttiributes = new ActivityTagsCollection(expectServiceAttiributesList); @@ -246,18 +246,18 @@ public void TestLocalRootProducerSpan() List> expectServiceAttiributesList = new List> { - new (AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), + new(AttributeAWSSpanKind, AutoInstrumentation.AwsSpanProcessingUtil.LocalRoot), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), }; List> expectDependencyAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Producer.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), - new (AttributeAWSRemoteService, this.awsRemoteServiceValue), - new (AttributeAWSRemoteOperation, this.awsRemoteOperationValue), + new(AttributeAWSSpanKind, ActivityKind.Producer.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.InternalOperation), + new(AttributeAWSRemoteService, this.awsRemoteServiceValue), + new(AttributeAWSRemoteOperation, this.awsRemoteOperationValue), }; ActivityTagsCollection expectServiceAttiributes = new ActivityTagsCollection(expectServiceAttiributesList); @@ -272,11 +272,11 @@ public void TestConsumerSpanWithAttributes() this.UpdateResourceWithServiceName(); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Consumer.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), - new (AttributeAWSRemoteService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteService), - new (AttributeAWSRemoteOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteOperation), + new(AttributeAWSSpanKind, ActivityKind.Consumer.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), + new(AttributeAWSRemoteService, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteService), + new(AttributeAWSRemoteOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownRemoteOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Consumer); @@ -290,9 +290,9 @@ public void TestServerSpanWithAttributes() this.UpdateResourceWithServiceName(); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, this.spanNameValue), + new(AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, this.spanNameValue), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(this.spanNameValue, ActivityKind.Server); @@ -307,9 +307,9 @@ public void TestServerSpanWithEmptySpanName() this.UpdateResourceWithServiceName(); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), + new(AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Server); @@ -323,9 +323,9 @@ public void TestServerSpanWithSpanNameAsHttpMethod() this.UpdateResourceWithServiceName(); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), + new(AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, AutoInstrumentation.AwsSpanProcessingUtil.UnknownOperation), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity("GET", ActivityKind.Server); @@ -341,9 +341,9 @@ public void TestServerSpanWithSpanNameWithHttpTarget() this.UpdateResourceWithServiceName(); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, "POST /payment"), + new(AttributeAWSSpanKind, ActivityKind.Server.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, "POST /payment"), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity("POST", ActivityKind.Server); @@ -359,11 +359,11 @@ public void TestProducerSpanWithAttributes() this.UpdateResourceWithServiceName(); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Producer.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, this.awsLocalOperationValue), - new (AttributeAWSRemoteService, this.awsRemoteServiceValue), - new (AttributeAWSRemoteOperation, this.awsRemoteOperationValue), + new(AttributeAWSSpanKind, ActivityKind.Producer.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, this.awsLocalOperationValue), + new(AttributeAWSRemoteService, this.awsRemoteServiceValue), + new(AttributeAWSRemoteOperation, this.awsRemoteOperationValue), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Producer); @@ -381,11 +381,11 @@ public void TestClientSpanWithAttributes() this.UpdateResourceWithServiceName(); List> expectAttributesList = new List> { - new (AttributeAWSSpanKind, ActivityKind.Client.ToString().ToUpper()), - new (AttributeAWSLocalService, this.serviceNameValue), - new (AttributeAWSLocalOperation, this.awsLocalOperationValue), - new (AttributeAWSRemoteService, this.awsRemoteServiceValue), - new (AttributeAWSRemoteOperation, this.awsRemoteOperationValue), + new(AttributeAWSSpanKind, ActivityKind.Client.ToString().ToUpper()), + new(AttributeAWSLocalService, this.serviceNameValue), + new(AttributeAWSLocalOperation, this.awsLocalOperationValue), + new(AttributeAWSRemoteService, this.awsRemoteServiceValue), + new(AttributeAWSRemoteOperation, this.awsRemoteOperationValue), }; ActivityTagsCollection expectedAttributes = new ActivityTagsCollection(expectAttributesList); Activity? spanDataMock = this.testSource.StartActivity(string.Empty, ActivityKind.Client); @@ -1500,8 +1500,8 @@ private void UpdateResourceWithServiceName() { List> resourceAttributes = new List> { - new (AutoInstrumentation.AwsMetricAttributeGenerator.AttributeServiceName, this.serviceNameValue), - new (AwsAttributeKeys.AttributeAWSLocalService, this.serviceNameValue), + new(AutoInstrumentation.AwsMetricAttributeGenerator.AttributeServiceName, this.serviceNameValue), + new(AwsAttributeKeys.AttributeAWSLocalService, this.serviceNameValue), }; this.resource = new Resource(resourceAttributes); } diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanMetricsProcessorTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanMetricsProcessorTest.cs index 6e4fd1cc..d78feb1c 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanMetricsProcessorTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanMetricsProcessorTest.cs @@ -15,6 +15,27 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] +public static class GlobalCallbackData +{ + public static List>? CallList { get; set; } + + public static void Clear() + { + CallList = null; + } +} + +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "Tests")] +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "Test helper enum")] +public enum ExpectedStatusMetric +{ + ERROR = 0, + FAULT = 1, + NEITHER = 2, +} + // There is two test that is not implemented in this Class, comparing with Java: // 1. testIsRequired() @@ -27,6 +48,7 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; // It either valid (set by passing a parent ID and automatically matching Activity.Parent field) // or just Null [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Test helper classes")] #pragma warning disable CS8604 // Possible null reference argument. #pragma warning disable CS8602 // Possible null reference argument. public class AwsSpanMetricsProcessorTest : IDisposable @@ -557,23 +579,3 @@ private void SetLatency(Activity? spanDataMock, double latency = -1) durationSetMethod?.Invoke(spanDataMock, new object?[] { timeSpan }); } } - -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] -public static class GlobalCallbackData -{ - public static List>? CallList { get; set; } - - public static void Clear() - { - CallList = null; - } -} - -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "Tests")] -public enum ExpectedStatusMetric -{ - ERROR = 0, - FAULT = 1, - NEITHER = 2, -} diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/OtlpAwsSpanExporterTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/OtlpAwsSpanExporterTest.cs index 1260bc64..9e804d61 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/OtlpAwsSpanExporterTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/OtlpAwsSpanExporterTest.cs @@ -17,6 +17,7 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Test helper classes")] public class OtlpAwsSpanExporterTest { private const string XrayOtlpEndpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"; @@ -68,14 +69,14 @@ public void TestAwsSpanExporterInjectSigV4Headers() Content = new StringContent(string.Empty), }; - (ExportResult result, HttpRequestMessage? capturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); + (ExportResult Result, HttpRequestMessage? CapturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); int callCount = mockAuth.CallCount; // Verify the result - Assert.Equal(ExportResult.Success, execute.result); + Assert.Equal(ExportResult.Success, execute.Result); Assert.Equal(1, callCount); - Assert.NotNull(execute.capturedRequest); - ValidateSigV4Headers(execute.capturedRequest, ExpectedAuth + callCount, ExpectedAmzDate + callCount, ExpectedAmzContentSha256 + callCount); + Assert.NotNull(execute.CapturedRequest); + ValidateSigV4Headers(execute.CapturedRequest, ExpectedAuth + callCount, ExpectedAmzDate + callCount, ExpectedAmzContentSha256 + callCount); } // Verifies that the exporter can successfully export multiple span requests with different sigv4 headers. @@ -96,14 +97,14 @@ public void TestAwsSpanExporterInjectsSigV4HeadersMultipleExports() for (int i = 1; i < 11; i += 1) { - (ExportResult result, HttpRequestMessage? capturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); + (ExportResult Result, HttpRequestMessage? CapturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); var callCount = mockAuth.CallCount; - Assert.Equal(ExportResult.Success, execute.result); + Assert.Equal(ExportResult.Success, execute.Result); Assert.Equal(i, callCount); - Assert.NotNull(execute.capturedRequest); - ValidateSigV4Headers(execute.capturedRequest, ExpectedAuth + callCount, ExpectedAmzDate + callCount, ExpectedAmzContentSha256 + callCount); + Assert.NotNull(execute.CapturedRequest); + ValidateSigV4Headers(execute.CapturedRequest, ExpectedAuth + callCount, ExpectedAmzDate + callCount, ExpectedAmzContentSha256 + callCount); } } @@ -129,13 +130,13 @@ public void TestAwsSpanExporterShouldNotRetryWithUnRetryableStatusCode() }; BaseExporter exporter = new OtlpAwsSpanExporter(this.options, this.tracerProvider.GetDefaultResource(), mockAuth); - (ExportResult result, HttpRequestMessage? capturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); + (ExportResult Result, HttpRequestMessage? CapturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); int callCount = mockAuth.CallCount; - Assert.Equal(ExportResult.Failure, execute.result); + Assert.Equal(ExportResult.Failure, execute.Result); Assert.Equal(1, callCount); - Assert.NotNull(execute.capturedRequest); - ValidateSigV4Headers(execute.capturedRequest, ExpectedAuth + callCount, ExpectedAmzDate + callCount, ExpectedAmzContentSha256 + callCount); + Assert.NotNull(execute.CapturedRequest); + ValidateSigV4Headers(execute.CapturedRequest, ExpectedAuth + callCount, ExpectedAmzDate + callCount, ExpectedAmzContentSha256 + callCount); } } @@ -164,13 +165,13 @@ public void TestAwsSpanExporterShouldRetryWithRetryableStatusCode() response.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromMilliseconds(500)); BaseExporter exporter = new OtlpAwsSpanExporter(this.options, this.tracerProvider.GetDefaultResource(), mockAuth); - (ExportResult result, HttpRequestMessage? capturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); + (ExportResult Result, HttpRequestMessage? CapturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); int callCount = mockAuth.CallCount; - Assert.Equal(ExportResult.Failure, execute.result); + Assert.Equal(ExportResult.Failure, execute.Result); Assert.Equal(2, callCount); - Assert.NotNull(execute.capturedRequest); - ValidateSigV4Headers(execute.capturedRequest, ExpectedAuth + callCount, ExpectedAmzDate + callCount, ExpectedAmzContentSha256 + callCount); + Assert.NotNull(execute.CapturedRequest); + ValidateSigV4Headers(execute.CapturedRequest, ExpectedAuth + callCount, ExpectedAmzDate + callCount, ExpectedAmzContentSha256 + callCount); } } @@ -189,10 +190,10 @@ public void TestAwsSpanExporterShouldRetryIfFailureToSignSigV4() }; this.options.TimeoutMilliseconds = 5000; BaseExporter exporter = new OtlpAwsSpanExporter(this.options, this.tracerProvider.GetDefaultResource(), mockAuth); - (ExportResult result, HttpRequestMessage? capturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); - Assert.Equal(ExportResult.Failure, execute.result); + (ExportResult Result, HttpRequestMessage? CapturedRequest) execute = SetupMockExporterAndCaptureRequest(exporter, response); + Assert.Equal(ExportResult.Failure, execute.Result); Assert.True(mockAuth.CallCount > 1); // The delay is random for exceptions. Hard to tell how times it retries. - Assert.Null(execute.capturedRequest); + Assert.Null(execute.CapturedRequest); } this.options.TimeoutMilliseconds = 1000; @@ -210,7 +211,7 @@ private static void ValidateSigV4Headers(HttpRequestMessage? capturedRequest, st Assert.Equal(expectedAmzContentSha256, capturedRequest.Headers.GetValues(XAmzContentSha256Header).First()); } - private static (ExportResult, HttpRequestMessage?) SetupMockExporterAndCaptureRequest(BaseExporter exporter, HttpResponseMessage response) + private static (ExportResult Result, HttpRequestMessage? CapturedRequest) SetupMockExporterAndCaptureRequest(BaseExporter exporter, HttpResponseMessage response) { HttpRequestMessage? capturedRequest = null; diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/RegionalResourceArnParserTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/RegionalResourceArnParserTest.cs index aa2f6b69..1a3edf9b 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/RegionalResourceArnParserTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/RegionalResourceArnParserTest.cs @@ -7,7 +7,7 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] -public class RegionalResourceArnParserTests +public class RegionalResourceArnParserTest { [Theory] [InlineData(null, null)] From 156d5a2a22e8e66d9e969fd0d8e6ccccca21e259 Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 21:19:02 -0700 Subject: [PATCH 10/13] more fixes --- ...Telemetry.AutoInstrumentation.Tests.csproj | 6 ++- ...wsBatchUnsampledSpanExportProcessorTest.cs | 2 +- .../AwsLambdaSpanProcessorTest.cs | 2 +- .../AwsSpanMetricsProcessorTest.cs | 43 +++++++++---------- .../AwsSpanProcessingUtilTest.cs | 11 +++-- .../OtlpAwsSpanExporterTest.cs | 1 - 6 files changed, 32 insertions(+), 33 deletions(-) diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj index 766c5827..a1a71060 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj @@ -10,8 +10,10 @@ true - $(NoWarn);SA0001;SA1300 + SA1204: Element ordering (test helper classes can appear in any order) + SA1300: Element naming (test namespace uses underscores by convention) + SA1402: Multiple types per file (test helper classes are acceptable) --> + $(NoWarn);SA0001;SA1204;SA1300;SA1402 diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsBatchUnsampledSpanExportProcessorTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsBatchUnsampledSpanExportProcessorTest.cs index 06635133..d3d61bf9 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsBatchUnsampledSpanExportProcessorTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsBatchUnsampledSpanExportProcessorTest.cs @@ -103,4 +103,4 @@ public void CheckThatUnSampledActivityIsProcessed() Assert.Equal(0, (long)droppedCount); } } -} \ No newline at end of file +} diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsLambdaSpanProcessorTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsLambdaSpanProcessorTest.cs index 6349ceaf..22beb2ac 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsLambdaSpanProcessorTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsLambdaSpanProcessorTest.cs @@ -86,4 +86,4 @@ public void CheckThatMultipleServerSpanFlagNotAdded() Assert.Null(lambdaActivity.GetTagItem(AttributeAWSTraceLambdaFlagMultipleServer)); } -} \ No newline at end of file +} diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanMetricsProcessorTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanMetricsProcessorTest.cs index d78feb1c..25c2e89a 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanMetricsProcessorTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanMetricsProcessorTest.cs @@ -15,27 +15,6 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] -public static class GlobalCallbackData -{ - public static List>? CallList { get; set; } - - public static void Clear() - { - CallList = null; - } -} - -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "Tests")] -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "Test helper enum")] -public enum ExpectedStatusMetric -{ - ERROR = 0, - FAULT = 1, - NEITHER = 2, -} - // There is two test that is not implemented in this Class, comparing with Java: // 1. testIsRequired() @@ -48,7 +27,6 @@ public enum ExpectedStatusMetric // It either valid (set by passing a parent ID and automatically matching Activity.Parent field) // or just Null [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Test helper classes")] #pragma warning disable CS8604 // Possible null reference argument. #pragma warning disable CS8602 // Possible null reference argument. public class AwsSpanMetricsProcessorTest : IDisposable @@ -579,3 +557,24 @@ private void SetLatency(Activity? spanDataMock, double latency = -1) durationSetMethod?.Invoke(spanDataMock, new object?[] { timeSpan }); } } + +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] +public static class GlobalCallbackData +{ + public static List>? CallList { get; set; } + + public static void Clear() + { + CallList = null; + } +} + +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "Tests")] +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "Test helper enum")] +public enum ExpectedStatusMetric +{ + ERROR = 0, + FAULT = 1, + NEITHER = 2, +} diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanProcessingUtilTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanProcessingUtilTest.cs index 91c0e874..16568c60 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanProcessingUtilTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AwsSpanProcessingUtilTest.cs @@ -3,12 +3,6 @@ using System.Diagnostics; using System.Reflection; -using static AWS.Distro.OpenTelemetry.AutoInstrumentation.AwsAttributeKeys; -using static AWS.Distro.OpenTelemetry.AutoInstrumentation.AwsSpanProcessingUtil; -using static OpenTelemetry.Trace.TraceSemanticConventions; - -namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; - using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; @@ -16,6 +10,11 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; using Microsoft.AspNetCore.Routing.Patterns; using Moq; using Xunit; +using static AWS.Distro.OpenTelemetry.AutoInstrumentation.AwsAttributeKeys; +using static AWS.Distro.OpenTelemetry.AutoInstrumentation.AwsSpanProcessingUtil; +using static OpenTelemetry.Trace.TraceSemanticConventions; + +namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] #pragma warning disable CS8602 // Possible null reference argument. diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/OtlpAwsSpanExporterTest.cs b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/OtlpAwsSpanExporterTest.cs index 9e804d61..03df5c31 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/OtlpAwsSpanExporterTest.cs +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/OtlpAwsSpanExporterTest.cs @@ -17,7 +17,6 @@ namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests; [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Tests")] -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Test helper classes")] public class OtlpAwsSpanExporterTest { private const string XrayOtlpEndpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"; From 1481724b7757ce9367719284080d85ee369d00cc Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 21:22:50 -0700 Subject: [PATCH 11/13] Fix --- ...AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj index a1a71060..19b2cfd0 100644 --- a/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj +++ b/test/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests/AWS.Distro.OpenTelemetry.AutoInstrumentation.Tests.csproj @@ -8,12 +8,13 @@ ../../buildtools/awsoteldotnet.snk false true - - $(NoWarn);SA0001;SA1204;SA1300;SA1402 + $(NoWarn);CS8002;SA0001;SA1204;SA1300;SA1402 From 29729db9a69edc249285805c34b945400c876b25 Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 21:30:35 -0700 Subject: [PATCH 12/13] Fix --- .../AwsSpanProcessingUtil.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsSpanProcessingUtil.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsSpanProcessingUtil.cs index bbe8523e..fc01a9dc 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsSpanProcessingUtil.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AwsSpanProcessingUtil.cs @@ -316,7 +316,7 @@ private static bool IsSqsReceiveMessageConsumerSpan(Activity span) string? serviceName = (string?)span.GetTagItem(AttributeAWSServiceName); return !string.IsNullOrEmpty(serviceName) - && serviceName.Equals(SQSService) + && SQSService.Equals(serviceName) && ActivityKind.Consumer.Equals(spanKind) && spanActivitySource != null && spanActivitySource.Name.StartsWith(ActivitySourceName) From 177431858c36d10993d3c137f8ea077029016723 Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Thu, 18 Sep 2025 21:36:01 -0700 Subject: [PATCH 13/13] fix --- src/AWS.Distro.OpenTelemetry.AutoInstrumentation/Plugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/Plugin.cs b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/Plugin.cs index 68d57407..9eb2c8d5 100644 --- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/Plugin.cs +++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/Plugin.cs @@ -359,11 +359,11 @@ public void ConfigureTracesOptions(HttpClientTraceInstrumentationOptions options #endif } +#if !NETFRAMEWORK /// /// Used to call ShouldSampleParent function /// /// options to configure -#if !NETFRAMEWORK public void ConfigureTracesOptions(AspNetCoreTraceInstrumentationOptions options) { options.EnrichWithHttpRequest = (activity, request) =>