From df1d425b52595cfb09ec036e37874c708762a403 Mon Sep 17 00:00:00 2001 From: Mahad Janjua Date: Mon, 10 Mar 2025 16:05:07 -0700 Subject: [PATCH 1/3] Test --- .../workflows/dotnet-ec2-adot-sigv4-test.yml | 225 ++++++++++++ .../workflows/python-ec2-adot-sigv4-test.yml | 1 + .github/workflows/test.yml | 24 ++ terraform/dotnet/ec2/adot-sigv4/main.tf | 315 +++++++++++++++++ terraform/dotnet/ec2/adot-sigv4/output.tf | 26 ++ terraform/dotnet/ec2/adot-sigv4/variables.tf | 42 +++ .../PredefinedExpectedTemplate.java | 20 ++ .../ec2/adot-sigv4/aws-sdk-call-log.mustache | 51 +++ .../adot-sigv4/aws-sdk-call-metric.mustache | 227 ++++++++++++ .../adot-sigv4/aws-sdk-call-trace.mustache | 65 ++++ .../ec2/adot-sigv4/client-call-log.mustache | 48 +++ .../adot-sigv4/client-call-metric.mustache | 227 ++++++++++++ .../ec2/adot-sigv4/client-call-trace.mustache | 71 ++++ .../outgoing-http-call-log.mustache | 48 +++ .../outgoing-http-call-metric.mustache | 227 ++++++++++++ .../outgoing-http-call-trace.mustache | 57 +++ .../adot-sigv4/remote-service-log.mustache | 48 +++ .../adot-sigv4/remote-service-metric.mustache | 326 ++++++++++++++++++ .../adot-sigv4/remote-service-trace.mustache | 72 ++++ .../dotnet/ec2/adot-sigv4/log-validation.yml | 25 ++ .../ec2/adot-sigv4/metric-validation.yml | 25 ++ .../ec2/adot-sigv4/trace-validation.yml | 24 ++ 22 files changed, 2194 insertions(+) create mode 100644 .github/workflows/dotnet-ec2-adot-sigv4-test.yml create mode 100644 .github/workflows/test.yml create mode 100644 terraform/dotnet/ec2/adot-sigv4/main.tf create mode 100644 terraform/dotnet/ec2/adot-sigv4/output.tf create mode 100644 terraform/dotnet/ec2/adot-sigv4/variables.tf create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-log.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-metric.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-log.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-metric.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-log.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-metric.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-log.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-metric.mustache create mode 100644 validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache create mode 100644 validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/log-validation.yml create mode 100644 validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/metric-validation.yml create mode 100644 validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/trace-validation.yml diff --git a/.github/workflows/dotnet-ec2-adot-sigv4-test.yml b/.github/workflows/dotnet-ec2-adot-sigv4-test.yml new file mode 100644 index 000000000..100412697 --- /dev/null +++ b/.github/workflows/dotnet-ec2-adot-sigv4-test.yml @@ -0,0 +1,225 @@ +## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +## SPDX-License-Identifier: Apache-2.0 + +# This is a reusable workflow for running the DotNet E2E Canary test for Application Signals. +# It is meant to be called from another workflow. +# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview +name: DotNet EC2 ADOT SigV4 (Stand-Alone ADOT) Use Case +on: + workflow_call: + inputs: + caller-workflow-name: + required: true + type: string + dotnet-version: + description: "Currently support version 6.0, 8.0" + required: false + type: string + default: '8.0' + staging_distro_name: + required: false + default: 'aws-opentelemetry-distro' + type: string + +permissions: + id-token: write + contents: read + +env: + E2E_TEST_AWS_REGION: 'us-west-2' + E2E_TEST_ACCOUNT_ID: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }} + E2E_TEST_ROLE_NAME: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }} + DOTNET_VERSION: ${{ inputs.dotnet-version }} + SAMPLE_APP_ZIP: s3://aws-appsignals-sample-app-prod-us-east-1/dotnet-sample-app-${{ inputs.dotnet-version }}.zip + METRIC_NAMESPACE: ApplicationSignals + LOG_GROUP_NAME: aws/spans + ADOT_DISTRO_NAME: ${{ inputs.staging_distro_name }} + TEST_RESOURCES_FOLDER: ${GITHUB_WORKSPACE} + +jobs: + dotnet-ec2-adot-sigv4: + runs-on: ubuntu-latest + steps: + - name: Check if the job started + id: job-started + run: echo "job-started=true" >> $GITHUB_OUTPUT + + - uses: actions/checkout@v4 + with: + repository: 'aws-observability/aws-application-signals-test-framework' + ref: ${{ inputs.caller-workflow-name == 'main-build' && 'main' || github.ref }} + fetch-depth: 0 + + - name: Initiate Gradlew Daemon + id: initiate-gradlew + uses: ./.github/workflows/actions/execute_and_retry + continue-on-error: true + with: + command: "./gradlew :validator:build" + cleanup: "./gradlew clean" + max_retry: 3 + sleep_time: 60 + + - name: Generate testing id + run: echo TESTING_ID="${{ github.run_id }}-${{ github.run_number }}-${RANDOM}" >> $GITHUB_ENV + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} + aws-region: ${{ env.E2E_TEST_AWS_REGION }} + + - name: Set Get ADOT Distro command environment variable + run: | + echo GET_ADOT_DISTRO_COMMAND="aws s3 cp s3://adot-autoinstrumentation-dotnet-staging/${{ env.ADOT_DISTRO_NAME }} ./${{ env.ADOT_DISTRO_NAME }} && unzip -d dotnet-distro ${{ env.ADOT_DISTRO_NAME }}" >> $GITHUB_ENV + # if [ "${{ github.event.repository.name }}" = "aws-otel-dotnet-instrumentation" ]; then + # # Get staging distro file from staging bucket + # echo GET_ADOT_DISTRO_COMMAND="aws s3 cp s3://adot-autoinstrumentation-dotnet-staging/${{ env.ADOT_DISTRO_NAME }} ./${{ env.ADOT_DISTRO_NAME }} && unzip -d dotnet-distro ${{ env.ADOT_DISTRO_NAME }}" >> $GITHUB_ENV + # else + # # After Release will switch to latest tag instead of hard code version for canary purpose + # echo GET_ADOT_DISTRO_COMMAND="wget -O aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip https://github.com/aws-observability/aws-otel-dotnet-instrumentation/releases/latest/download/aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip && unzip -d dotnet-distro aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip" >> $GITHUB_ENV + # fi + + - name: Set up terraform + uses: ./.github/workflows/actions/execute_and_retry + with: + command: "wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg" + post-command: 'echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list + && sudo apt update && sudo apt install terraform' + sleep_time: 60 + + - name: Initiate Terraform + uses: ./.github/workflows/actions/execute_and_retry + with: + command: "cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/dotnet/ec2/adot-sigv4 && terraform init && terraform validate" + cleanup: "rm -rf .terraform && rm -rf .terraform.lock.hcl" + max_retry: 6 + sleep_time: 60 + + - name: Deploy sample app via terraform and wait for endpoint to come online + working-directory: terraform/dotnet/ec2/adot-sigv4 + run: | + # Attempt to deploy the sample app on an EC2 instance and wait for its endpoint to come online. + # There may be occasional failures due to transitivity issues, so try up to 2 times. + # deployment_failed of 0 indicates that both the terraform deployment and the endpoint are running, while 1 indicates + # that it failed at some point + retry_counter=0 + max_retry=2 + while [ $retry_counter -lt $max_retry ]; do + echo "Attempt $retry_counter" + deployment_failed=0 + terraform apply -auto-approve \ + -var="aws_region=${{ env.E2E_TEST_AWS_REGION }}" \ + -var="test_id=${{ env.TESTING_ID }}" \ + -var="sample_app_zip=${{ env.SAMPLE_APP_ZIP }}" \ + -var="get_adot_distro_command=${{ env.GET_ADOT_DISTRO_COMMAND }}" \ + -var="language_version=${{ env.DOTNET_VERSION }}" \ + || deployment_failed=$? + + if [ $deployment_failed -eq 1 ]; then + echo "Terraform deployment was unsuccessful. Will attempt to retry deployment." + fi + + # If the success is 1 then either the terraform deployment or the endpoint connection failed, so first destroy the + # resources created from terraform and try again. + if [ $deployment_failed -eq 1 ]; then + echo "Destroying terraform" + terraform destroy -auto-approve \ + -var="test_id=${{ env.TESTING_ID }}" + + retry_counter=$(($retry_counter+1)) + else + # If deployment succeeded, then exit the loop + break + fi + + if [ $retry_counter -eq $max_retry ]; then + echo "Max retry reached, failed to deploy terraform and connect to the endpoint. Exiting code" + exit 1 + fi + done + + - name: Get the sample app endpoint + working-directory: terraform/dotnet/ec2/adot-sigv4 + run: | + echo "EC2_INSTANCE_AMI=$(terraform output ec2_instance_ami)" >> $GITHUB_ENV + echo "REMOTE_SERVICE_IP=$(terraform output sample_app_remote_service_private_ip)" >> $GITHUB_ENV + echo "MAIN_SERVICE_INSTANCE_ID=$(terraform output main_service_instance_id)" >> $GITHUB_ENV + + - name: Initiate Gradlew Daemon + if: steps.initiate-gradlew == 'failure' + uses: ./.github/workflows/actions/execute_and_retry + continue-on-error: true + with: + command: "./gradlew" + cleanup: "./gradlew clean" + max_retry: 3 + sleep_time: 60 + + # Validation for pulse telemetry data + - name: Validate generated EMF logs + id: log-validation + run: ./gradlew validator:run --args='-c dotnet/ec2/adot-sigv4/log-validation.yml + --testing-id ${{ env.TESTING_ID }} + --endpoint http://localhost:8080 + --remote-service-deployment-name ${{ env.REMOTE_SERVICE_IP }}:8081 + --region ${{ env.E2E_TEST_AWS_REGION }} + --metric-namespace ${{ env.METRIC_NAMESPACE }} + --log-group ${{ env.LOG_GROUP_NAME }} + --service-name dotnet-sample-application-${{ env.TESTING_ID }} + --remote-service-name dotnet-sample-remote-application-${{ env.TESTING_ID }} + --query-string ip=${{ env.REMOTE_SERVICE_IP }}&testingId=${{ env.TESTING_ID }} + --instance-ami ${{ env.EC2_INSTANCE_AMI }} + --instance-id ${{ env.MAIN_SERVICE_INSTANCE_ID }} + --rollup' + + - name: Validate generated metrics + id: metric-validation + if: (success() || steps.log-validation.outcome == 'failure') && !cancelled() + run: ./gradlew validator:run --args='-c dotnet/ec2/adot-sigv4/metric-validation.yml + --testing-id ${{ env.TESTING_ID }} + --endpoint http://localhost:8080 + --remote-service-deployment-name ${{ env.REMOTE_SERVICE_IP }}:8081 + --region ${{ env.E2E_TEST_AWS_REGION }} + --metric-namespace ${{ env.METRIC_NAMESPACE }} + --log-group ${{ env.LOG_GROUP_NAME }} + --service-name dotnet-sample-application-${{ env.TESTING_ID }} + --remote-service-name dotnet-sample-remote-application-${{ env.TESTING_ID }} + --query-string ip=${{ env.REMOTE_SERVICE_IP }} + --instance-ami ${{ env.EC2_INSTANCE_AMI }} + --instance-id ${{ env.MAIN_SERVICE_INSTANCE_ID }} + --rollup' + + - name: Validate generated traces + id: trace-validation + if: (success() || steps.log-validation.outcome == 'failure' || steps.metric-validation.outcome == 'failure') && !cancelled() + run: ./gradlew validator:run --args='-c dotnet/ec2/adot-sigv4/trace-validation.yml + --testing-id ${{ env.TESTING_ID }} + --endpoint http://localhost:8080 + --remote-service-deployment-name ${{ env.REMOTE_SERVICE_IP }}:8081 + --region ${{ env.E2E_TEST_AWS_REGION }} + --account-id ${{ env.E2E_TEST_ACCOUNT_ID }} + --metric-namespace ${{ env.METRIC_NAMESPACE }} + --log-group ${{ env.LOG_GROUP_NAME }} + --service-name dotnet-sample-application-${{ env.TESTING_ID }} + --remote-service-name dotnet-sample-remote-application-${{ env.TESTING_ID }} + --query-string ip=${{ env.REMOTE_SERVICE_IP }}&testingId=${{ env.TESTING_ID }} + --instance-ami ${{ env.EC2_INSTANCE_AMI }} + --instance-id ${{ env.MAIN_SERVICE_INSTANCE_ID }} + --rollup' + + - name: Refresh AWS Credentials + if: always() + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} + aws-region: ${{ env.E2E_TEST_AWS_REGION }} + + # Clean up Procedures + - name: Terraform destroy + if: always() + continue-on-error: true + working-directory: terraform/dotnet/ec2/adot-sigv4 + run: | + terraform destroy -auto-approve \ + -var="test_id=${{ env.TESTING_ID }}" \ No newline at end of file diff --git a/.github/workflows/python-ec2-adot-sigv4-test.yml b/.github/workflows/python-ec2-adot-sigv4-test.yml index 6febd034e..f550dd340 100644 --- a/.github/workflows/python-ec2-adot-sigv4-test.yml +++ b/.github/workflows/python-ec2-adot-sigv4-test.yml @@ -220,6 +220,7 @@ jobs: --rollup' - name: Refresh AWS Credentials + if: always() uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..03ad88c6a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,24 @@ +## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +## SPDX-License-Identifier: Apache-2.0 + +# This is a reusable workflow for running the Enablement test for App Signals. +# It is meant to be called from another workflow. +# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview +name: Test +on: + push: + branches: + - dotnet-sigv4 + +permissions: + id-token: write + contents: read + +jobs: + # Runs in us-west-1 using us-east-1 account + dotnet-ec2-adot-sigv4: + uses: ./.github/workflows/dotnet-ec2-adot-sigv4-test.yml + secrets: inherit + with: + caller-workflow-name: 'test' + staging_distro_name: 'aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip' \ No newline at end of file diff --git a/terraform/dotnet/ec2/adot-sigv4/main.tf b/terraform/dotnet/ec2/adot-sigv4/main.tf new file mode 100644 index 000000000..9bb39d755 --- /dev/null +++ b/terraform/dotnet/ec2/adot-sigv4/main.tf @@ -0,0 +1,315 @@ +# ------------------------------------------------------------------------ +# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# A copy of the License is located at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# or in the "license" file accompanying this file. This file is distributed +# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +# express or implied. See the License for the specific language governing +# permissions and limitations under the License. +# ------------------------------------------------------------------------- + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + } + } +} + +# Define the provider for AWS +provider "aws" {} + +resource "aws_default_vpc" "default" {} + +resource "tls_private_key" "ssh_key" { + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "aws_key_pair" "aws_ssh_key" { + key_name = "instance_key-${var.test_id}" + public_key = tls_private_key.ssh_key.public_key_openssh +} + +locals { + ssh_key_name = aws_key_pair.aws_ssh_key.key_name + private_key_content = tls_private_key.ssh_key.private_key_pem +} + +data "aws_ami" "ami" { + owners = ["amazon"] + most_recent = true + filter { + name = "name" + values = ["al20*-ami-minimal-*-x86_64"] + } + filter { + name = "state" + values = ["available"] + } + filter { + name = "architecture" + values = ["x86_64"] + } + filter { + name = "image-type" + values = ["machine"] + } + + filter { + name = "root-device-name" + values = ["/dev/xvda"] + } + + filter { + name = "root-device-type" + values = ["ebs"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } +} + +resource "aws_instance" "main_service_instance" { + ami = data.aws_ami.ami.id # Amazon Linux 2 (free tier) + instance_type = "t3.small" + key_name = local.ssh_key_name + iam_instance_profile = "APP_SIGNALS_EC2_TEST_ROLE" + vpc_security_group_ids = [aws_default_vpc.default.default_security_group_id] + associate_public_ip_address = true + instance_initiated_shutdown_behavior = "terminate" + + metadata_options { + http_tokens = "required" + } + + root_block_device { + volume_size = 5 + } + + tags = { + Name = "main-service-${var.test_id}" + } +} + +resource "null_resource" "main_service_setup" { + connection { + type = "ssh" + user = var.user + private_key = local.private_key_content + host = aws_instance.main_service_instance.public_ip + } + + provisioner "remote-exec" { + inline = [ + <<-EOF + #!/bin/bash + + # Install DotNet and wget + sudo yum install -y wget + sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc + sudo wget -O /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/37/prod.repo + sudo dnf install -y dotnet-sdk-${var.language_version} + sudo yum install unzip -y + + # enable ec2 instance connect for debug + sudo yum install ec2-instance-connect -y + + # Get ADOT distro and unzip it + ${var.get_adot_distro_command} + + # Get and run the sample application with configuration + aws s3 cp ${var.sample_app_zip} ./dotnet-sample-app.zip + unzip -o dotnet-sample-app.zip + + # Get Absolute Path + current_dir=$(pwd) + echo $current_dir + + # Export environment variables for instrumentation + cd ./asp_frontend_service + dotnet build + CORECLR_ENABLE_PROFILING=1 \ + CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318} \ + CORECLR_PROFILER_PATH=$current_dir/dotnet-distro/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so \ + DOTNET_ADDITIONAL_DEPS=$current_dir/dotnet-distro/AdditionalDeps \ + DOTNET_SHARED_STORE=$current_dir/dotnet-distro/store \ + DOTNET_STARTUP_HOOKS=$current_dir/dotnet-distro/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll \ + OTEL_DOTNET_AUTO_HOME=$current_dir/dotnet-distro \ + OTEL_DOTNET_AUTO_PLUGINS="AWS.Distro.OpenTelemetry.AutoInstrumentation.Plugin, AWS.Distro.OpenTelemetry.AutoInstrumentation" \ + OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \ + OTEL_LOGS_EXPORTER=none \ + OTEL_METRICS_EXPORTER=none \ + OTEL_TRACES_EXPORTER=none \ + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://xray.${var.aws_region}.amazonaws.com/v1/traces \ + OTEL_AWS_SIG_V4_ENABLED=true \ + OTEL_TRACES_SAMPLER=xray \ + OTEL_RESOURCE_ATTRIBUTES=service.name=dotnet-sample-application-${var.test_id} \ + ASPNETCORE_URLS=http://0.0.0.0:8080 \ + nohup dotnet bin/Debug/netcoreapp${var.language_version}/asp_frontend_service.dll &> nohup.out & + + # The application needs time to come up and reach a steady state, this should not take longer than 30 seconds + sleep 30 + + # Check if the application is up. If it is not up, then exit 1. + attempt_counter=0 + max_attempts=30 + until $(curl --output /dev/null --silent --fail $(echo "http://localhost:8080" | tr -d '"')); do + if [ $attempt_counter -eq $max_attempts ];then + echo "Failed to connect to endpoint. Will attempt to redeploy sample app." + deployment_failed=1 + break + fi + echo "Attempting to connect to the main endpoint. Tried $attempt_counter out of $max_attempts" + attempt_counter=$(($attempt_counter+1)) + sleep 10 + done + + EOF + ] + } + + depends_on = [aws_instance.main_service_instance] +} + +resource "aws_instance" "remote_service_instance" { + ami = data.aws_ami.ami.id # Amazon Linux 2 (free tier) + instance_type = "t3.small" + key_name = local.ssh_key_name + iam_instance_profile = "APP_SIGNALS_EC2_TEST_ROLE" + vpc_security_group_ids = [aws_default_vpc.default.default_security_group_id] + associate_public_ip_address = true + instance_initiated_shutdown_behavior = "terminate" + + metadata_options { + http_tokens = "required" + } + + root_block_device { + volume_size = 5 + } + + tags = { + Name = "remote-service-${var.test_id}" + } +} + +resource "null_resource" "remote_service_setup" { + connection { + type = "ssh" + user = var.user + private_key = local.private_key_content + host = aws_instance.remote_service_instance.public_ip + } + + provisioner "remote-exec" { + inline = [ + <<-EOF + #!/bin/bash + + # Install DotNet and wget + sudo yum install -y wget + sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc + sudo wget -O /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/37/prod.repo + sudo dnf install -y dotnet-sdk-${var.language_version} + sudo yum install unzip -y + + # enable ec2 instance connect for debug + sudo yum install ec2-instance-connect -y + + # Get ADOT distro and unzip it + ${var.get_adot_distro_command} + + # Get and run the sample application with configuration + aws s3 cp ${var.sample_app_zip} ./dotnet-sample-app.zip + unzip -o dotnet-sample-app.zip + + # Get Absolute Path + current_dir=$(pwd) + echo $current_dir + + # Export environment variables for instrumentation + cd ./asp_remote_service + dotnet build + CORECLR_ENABLE_PROFILING=1 \ + CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318} \ + CORECLR_PROFILER_PATH=$current_dir/dotnet-distro/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so \ + DOTNET_ADDITIONAL_DEPS=$current_dir/dotnet-distro/AdditionalDeps \ + DOTNET_SHARED_STORE=$current_dir/dotnet-distro/store \ + DOTNET_STARTUP_HOOKS=$current_dir/dotnet-distro/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll \ + OTEL_DOTNET_AUTO_HOME=$current_dir/dotnet-distro \ + OTEL_DOTNET_AUTO_PLUGINS="AWS.Distro.OpenTelemetry.AutoInstrumentation.Plugin, AWS.Distro.OpenTelemetry.AutoInstrumentation" \ + OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \ + OTEL_LOGS_EXPORTER=none \ + OTEL_METRICS_EXPORTER=none \ + OTEL_TRACES_EXPORTER=none \ + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://xray.${var.aws_region}.amazonaws.com/v1/traces \ + OTEL_AWS_SIG_V4_ENABLED=true \ + OTEL_TRACES_SAMPLER=xray \ + OTEL_RESOURCE_ATTRIBUTES=service.name=dotnet-sample-remote-application-${var.test_id} \ + ASPNETCORE_URLS=http://0.0.0.0:8081 \ + nohup dotnet bin/Debug/netcoreapp${var.language_version}/asp_remote_service.dll &> nohup.out & + + # The application needs time to come up and reach a steady state, this should not take longer than 30 seconds + sleep 30 + + # Check if the application is up. If it is not up, then exit 1. + attempt_counter=0 + max_attempts=30 + until $(curl --output /dev/null --silent --fail $(echo "http://localhost:8081" | tr -d '"')); do + if [ $attempt_counter -eq $max_attempts ];then + echo "Failed to connect to endpoint. Will attempt to redeploy sample app." + deployment_failed=1 + break + fi + echo "Attempting to connect to the remote endpoint. Tried $attempt_counter out of $max_attempts" + attempt_counter=$(($attempt_counter+1)) + sleep 10 + done + + EOF + ] + } + + depends_on = [aws_instance.remote_service_instance] +} + +resource "null_resource" "traffic_generator_setup" { + connection { + type = "ssh" + user = var.user + private_key = local.private_key_content + host = aws_instance.main_service_instance.public_ip + } + + provisioner "remote-exec" { + inline = [ + <<-EOF + sudo yum install nodejs aws-cli unzip tmux -y + + # Bring in the traffic generator files to EC2 Instance + aws s3 cp s3://aws-appsignals-sample-app-prod-us-east-1/traffic-generator.zip ./traffic-generator.zip + unzip ./traffic-generator.zip -d ./ + + # Install the traffic generator dependencies + npm install + + tmux new -s traffic-generator -d + tmux send-keys -t traffic-generator "export MAIN_ENDPOINT=\"localhost:8080\"" C-m + tmux send-keys -t traffic-generator "export REMOTE_ENDPOINT=\"${aws_instance.remote_service_instance.private_ip}\"" C-m + tmux send-keys -t traffic-generator "export ID=\"${var.test_id}\"" C-m + tmux send-keys -t traffic-generator "npm start" C-m + + EOF + ] + } + + depends_on = [null_resource.main_service_setup, null_resource.remote_service_setup] +} diff --git a/terraform/dotnet/ec2/adot-sigv4/output.tf b/terraform/dotnet/ec2/adot-sigv4/output.tf new file mode 100644 index 000000000..be572868a --- /dev/null +++ b/terraform/dotnet/ec2/adot-sigv4/output.tf @@ -0,0 +1,26 @@ +# ------------------------------------------------------------------------ +# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# A copy of the License is located at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# or in the "license" file accompanying this file. This file is distributed +# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +# express or implied. See the License for the specific language governing +# permissions and limitations under the License. +# ------------------------------------------------------------------------- + +output "sample_app_remote_service_private_ip" { + value = aws_instance.remote_service_instance.private_ip +} + +output "main_service_instance_id" { + value = aws_instance.main_service_instance.id +} + +output "ec2_instance_ami" { + value = data.aws_ami.ami.id +} \ No newline at end of file diff --git a/terraform/dotnet/ec2/adot-sigv4/variables.tf b/terraform/dotnet/ec2/adot-sigv4/variables.tf new file mode 100644 index 000000000..a0e19912d --- /dev/null +++ b/terraform/dotnet/ec2/adot-sigv4/variables.tf @@ -0,0 +1,42 @@ +# ------------------------------------------------------------------------ +# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# A copy of the License is located at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# or in the "license" file accompanying this file. This file is distributed +# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +# express or implied. See the License for the specific language governing +# permissions and limitations under the License. +# ------------------------------------------------------------------------- + +variable "test_id" { + default = "dummy-123" +} + +variable "aws_region" { + default = "" +} + +variable "user" { + default = "ec2-user" +} + +variable "sample_app_zip" { + default = "s3:///" +} + +variable "get_adot_distro_command" { + default = "aws s3 cp s3:/// ./ && unzip " +} + +variable "canary_type" { + default = "dotnet-ec2-default" +} + +variable "language_version" { + default = "8.0" +} \ No newline at end of file diff --git a/validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java b/validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java index 4e890a2e6..fc80e336c 100644 --- a/validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java +++ b/validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java @@ -304,6 +304,26 @@ public enum PredefinedExpectedTemplate implements FileConfig { DOTNET_EC2_ASG_CLIENT_CALL_METRIC("/expected-data-template/dotnet/ec2/asg/client-call-metric.mustache"), DOTNET_EC2_ASG_CLIENT_CALL_TRACE("/expected-data-template/dotnet/ec2/asg/client-call-trace.mustache"), + /** Python EC2 ADOT SigV4 (Stand Alone ADOT) Test Case Validations */ + DOTNET_EC2_ADOT_SIGV4_OUTGOING_HTTP_CALL_LOG( + "/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-log.mustache"), + DOTNET_EC2_ADOT_SIGV4_OUTGOING_HTTP_CALL_METRIC( + "/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-metric.mustache"), + DOTNET_EC2_ADOT_SIGV4_OUTGOING_HTTP_CALL_TRACE( + "/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache"), + + DOTNET_EC2_ADOT_SIGV4_AWS_SDK_CALL_LOG("/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-log.mustache"), + DOTNET_EC2_ADOT_SIGV4_AWS_SDK_CALL_METRIC("/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-metric.mustache"), + DOTNET_EC2_ADOT_SIGV4_AWS_SDK_CALL_TRACE("/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache"), + + DOTNET_EC2_ADOT_SIGV4_REMOTE_SERVICE_LOG("/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-log.mustache"), + DOTNET_EC2_ADOT_SIGV4_REMOTE_SERVICE_METRIC("/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-metric.mustache"), + DOTNET_EC2_ADOT_SIGV4_REMOTE_SERVICE_TRACE("/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache"), + + DOTNET_EC2_ADOT_SIGV4_CLIENT_CALL_LOG("/expected-data-template/dotnet/ec2/adot-sigv4/client-call-log.mustache"), + DOTNET_EC2_ADOT_SIGV4_CLIENT_CALL_METRIC("/expected-data-template/dotnet/ec2/adot-sigv4/client-call-metric.mustache"), + DOTNET_EC2_ADOT_SIGV4_CLIENT_CALL_TRACE("/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache"), + /** DotNet K8s Test Case Validations */ DOTNET_K8S_OUTGOING_HTTP_CALL_LOG("/expected-data-template/dotnet/k8s/outgoing-http-call-log.mustache"), DOTNET_K8S_OUTGOING_HTTP_CALL_METRIC("/expected-data-template/dotnet/k8s/outgoing-http-call-metric.mustache"), diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-log.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-log.mustache new file mode 100644 index 000000000..5a6963fb3 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-log.mustache @@ -0,0 +1,51 @@ +[{ + "name": "GET aws-sdk-call", + "kind": "SERVER", + "resource": { + "attributes": { + "aws.local.service": "{{serviceName}}", + "service.name": "{{serviceName}}", + "cloud.provider": "aws", + "cloud.region": "{{region}}", + "cloud.account.id": "{{accountId}}", + "cloud.platform": "aws_ec2" + } + }, + "attributes": { + "aws.local.service": "{{serviceName}}", + "aws.local.environment": "ec2:default", + "aws.local.operation": "GET aws-sdk-call", + "aws.span.kind": "LOCAL_ROOT", + "url.query": "^\\?ip=Redacted&testingId=Redacted$", + "http.route": "aws-sdk-call", + "http.request.method": "GET", + "PlatformType": "AWS::EC2" + } +}, +{ + "name": "S3.GetBucketLocation", + "kind": "CLIENT", + "resource": { + "attributes": { + "aws.local.service": "{{serviceName}}", + "service.name": "{{serviceName}}", + "cloud.provider": "aws", + "cloud.region": "{{region}}", + "cloud.account.id": "{{accountId}}", + "cloud.platform": "aws_ec2" + } + }, + "attributes": { + "aws.local.service": "{{serviceName}}", + "aws.local.operation": "UnmappedOperation", + "aws.remote.service": "AWS::S3", + "aws.remote.operation": "GetBucketLocation", + "aws.local.environment": "ec2:default", + "aws.service": "S3", + "aws.operation": "GetBucketLocation", + "aws.s3.bucket": "{{testingId}}", + "aws.span.kind": "CLIENT", + "aws.region": "{{region}}", + "PlatformType": "AWS::EC2" + } +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-metric.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-metric.mustache new file mode 100644 index 000000000..92e8104d3 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-metric.mustache @@ -0,0 +1,227 @@ +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: AWS::S3 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: AWS::S3 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET aws-sdk-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: AWS::S3 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GetBucketLocation + - + name: RemoteService + value: AWS::S3 \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache new file mode 100644 index 000000000..b38dccc35 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache @@ -0,0 +1,65 @@ +[{ + "name": "^{{serviceName}}$", + "http": { + "request": { + "url": "^{{endpoint}}/aws-sdk-call\\?ip=(([0-9]{1,3}.){3}[0-9]{1,3})&testingId={{testingId}}$", + "method": "^GET$" + } + }, + "aws": { + "ec2": { + "instance_id": "^{{instanceId}}$" + }, + "span.kind": "^LOCAL_ROOT$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET aws-sdk-call$", + "aws.local.environment": "^ec2:default$", + "span.name": "^GET aws-sdk-call$", + "span.kind": "^SERVER$" + }, + "metadata": { + "http.url": "^{{endpoint}}/aws-sdk-call\\?ip=(([0-9]{1,3}.){3}[0-9]{1,3})&testingId={{testingId}}$", + "http.method": "^GET$", + "http.route": "^aws-sdk-call$", + "service.name": "^{{serviceName}}$", + "cloud.provider": "^aws$", + "cloud.account.id": "^{{accountId}}$", + "cloud.region": "^{{region}}$", + "cloud.platform": "^aws_ec2$", + "PlatformType": "^AWS::EC2$" + }, + "subsegments": [ + { + "name": "^S3$", + "aws": { + "bucket_name": "^e2e-test-bucket-name-{{testingId}}$", + "s3.bucket": "^e2e-test-bucket-name-{{testingId}}$", + "span.kind": "^CLIENT$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^UnmappedOperation$", + "aws.remote.service": "^AWS::S3$", + "aws.remote.operation": "^GetBucketLocation$", + "aws.local.environment": "^ec2:default$", + "span.name": "^S3.GetBucketLocation$", + "span.kind": "^CLIENT$" + }, + "namespace": "^aws$" + } + ] +}, +{ + "name": "^S3$", + "aws": { + "bucket_name": "^e2e-test-bucket-name-{{testingId}}$", + "s3.bucket": "^e2e-test-bucket-name-{{testingId}}$", + "span.kind": "^CLIENT$" + }, + "annotations": { + "aws.local.service": "^AWS::S3$", + "aws.local.operation": "^GetBucketLocation$" + } +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-log.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-log.mustache new file mode 100644 index 000000000..ffbb712c5 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-log.mustache @@ -0,0 +1,48 @@ +[{ + "name": "GET client-call", + "kind": "SERVER", + "resource": { + "attributes": { + "aws.local.service": "{{serviceName}}", + "service.name": "{{serviceName}}", + "cloud.provider": "aws", + "cloud.region": "{{region}}", + "cloud.account.id": "{{accountId}}", + "cloud.platform": "aws_ec2" + } + }, + "attributes": { + "aws.local.service": "{{serviceName}}", + "aws.local.environment": "ec2:default", + "aws.local.operation": "GET client-call", + "aws.span.kind": "LOCAL_ROOT", + "http.route": "client-call", + "http.request.method": "GET", + "PlatformType": "AWS::EC2" + } +}, +{ + "name": "GET", + "kind": "CLIENT", + "resource": { + "attributes": { + "aws.local.service": "{{serviceName}}", + "service.name": "{{serviceName}}", + "cloud.provider": "aws", + "cloud.region": "{{region}}", + "cloud.account.id": "{{accountId}}", + "cloud.platform": "aws_ec2" + } + }, + "attributes": { + "aws.local.service": "{{serviceName}}", + "aws.local.operation": "InternalOperation", + "aws.remote.service": "local-root-client-call:80", + "aws.remote.operation": "GET /", + "aws.local.environment": "ec2:default", + "aws.span.kind": "LOCAL_ROOT", + "url.full": "http://local-root-client-call/", + "http.request.method": "GET", + "PlatformType": "AWS::EC2" + } +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-metric.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-metric.mustache new file mode 100644 index 000000000..85ed2565c --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-metric.mustache @@ -0,0 +1,227 @@ +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Operation + value: InternalOperation + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 + - + name: RemoteOperation + value: GET / + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: local-root-client-call:80 \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache new file mode 100644 index 000000000..261cfbac2 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache @@ -0,0 +1,71 @@ +[{ + "name": "^{{serviceName}}$", + "aws": { + "ec2": { + "instance_id": "^{{instanceId}}$" + } + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^InternalOperation$", + "aws.local.environment": "^ec2:default$", + "span.name": "^InternalOperation$", + "span.kind": "^SERVER$" + }, + "metadata": { + "service.name": "^{{serviceName}}$", + "cloud.provider": "^aws$", + "cloud.account.id": "^{{accountId}}$", + "cloud.region": "^{{region}}$", + "cloud.platform": "^aws_ec2$" + }, + "subsegments": [ + { + "name": "^local-root-client-call$", + "http": { + "request": { + "url": "^http://local-root-client-call/$", + "method": "^GET$" + } + }, + "aws": { + "ec2": { + "instance_id": "^{{instanceId}}$" + }, + "span.kind": "^LOCAL_ROOT$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^InternalOperation$", + "aws.remote.service": "^local-root-client-call$", + "aws.remote.operation": "GET /", + "aws.local.environment": "^ec2:default$", + "span.name": "^GET$", + "span.kind": "^CLIENT$" + }, + "metadata": { + "service.name": "^{{serviceName}}$", + "http.url": "^http://local-root-client-call/$", + "http.method": "^GET$", + "cloud.provider": "^aws$", + "cloud.account.id": "^{{accountId}}$", + "cloud.region": "^{{region}}$", + "cloud.platform": "^aws_ec2$" + }, + "namespace": "^remote$" + } + ] +}, +{ + "name": "^local-root-client-call$", + "http": { + "request": { + "url": "^http://local-root-client-call/$", + "method": "^GET$" + } + }, + "annotations": { + "aws.local.service": "^local-root-client-call$", + "aws.local.operation": "^GET /$" + } +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-log.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-log.mustache new file mode 100644 index 000000000..7836783f4 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-log.mustache @@ -0,0 +1,48 @@ +[{ + "name": "GET outgoing-http-call", + "kind": "SERVER", + "resource": { + "attributes": { + "aws.local.service": "{{serviceName}}", + "service.name": "{{serviceName}}", + "cloud.provider": "aws", + "cloud.region": "{{region}}", + "cloud.account.id": "{{accountId}}", + "cloud.platform": "aws_ec2" + } + }, + "attributes": { + "aws.local.service": "{{serviceName}}", + "aws.local.environment": "ec2:default", + "aws.local.operation": "GET outgoing-http-call", + "aws.span.kind": "LOCAL_ROOT", + "http.route": "outgoing-http-call", + "http.request.method": "GET", + "PlatformType": "AWS::EC2" + } +}, +{ + "name": "GET", + "kind": "CLIENT", + "resource": { + "attributes": { + "aws.local.service": "{{serviceName}}", + "service.name": "{{serviceName}}", + "cloud.provider": "aws", + "cloud.region": "{{region}}", + "cloud.account.id": "{{accountId}}", + "cloud.platform": "aws_ec2" + } + }, + "attributes": { + "aws.local.service": "{{serviceName}}", + "aws.local.operation": "UnmappedOperation", + "aws.remote.service": "aws.amazon.com:443", + "aws.remote.operation": "GET /", + "aws.local.environment": "ec2:default", + "aws.span.kind": "CLIENT", + "url.full": "https://aws.amazon.com/", + "http.request.method": "GET", + "PlatformType": "AWS::EC2" + } +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-metric.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-metric.mustache new file mode 100644 index 000000000..b8dae9528 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-metric.mustache @@ -0,0 +1,227 @@ +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET outgoing-http-call + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET / + - + name: RemoteService + value: aws.amazon.com:443 + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: aws.amazon.com:443 diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache new file mode 100644 index 000000000..831649e19 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache @@ -0,0 +1,57 @@ +[{ + "name": "^{{serviceName}}$", + "http": { + "request": { + "url": "^{{endpoint}}/outgoing-http-call$", + "method": "^GET$" + } + }, + "aws": { + "ec2": { + "instance_id": "^{{instanceId}}$" + }, + "span.kind": "^LOCAL_ROOT$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET outgoing-http-call$", + "aws.local.environment": "^ec2:default$", + "span.name": "^GET outgoing-http-call$", + "span.kind": "^SERVER$" + }, + "metadata": { + "http.url": "^{{endpoint}}/outgoing-http-call$", + "http.method": "^GET$", + "http.route": "^outgoing-http-call$", + "service.name": "^{{serviceName}}$", + "cloud.provider": "^aws$", + "cloud.account.id": "^{{accountId}}$", + "cloud.region": "^{{region}}$", + "cloud.platform": "^aws_ec2$", + "PlatformType": "^AWS::EC2$" + }, + "subsegments": [ + { + "name": "^www.amazon.com$", + "http": { + "request": { + "url": "^https://www.amazon.com/$", + "method": "^GET$" + } + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^UnmappedOperation$", + "aws.remote.service": "^www.amazon.com$", + "aws.remote.operation": "^GET /$", + "aws.local.environment": "^ec2:default$", + "span.name": "^GET$", + "span.kind": "^CLIENT$" + }, + "namespace": "^remote$" + } + ] +}, +{ + "name": "^www.amazon.com$" +}] diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-log.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-log.mustache new file mode 100644 index 000000000..9f84036e7 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-log.mustache @@ -0,0 +1,48 @@ +[{ + "name": "GET remote-service", + "kind": "SERVER", + "resource": { + "attributes": { + "aws.local.service": "{{serviceName}}", + "service.name": "{{serviceName}}", + "cloud.provider": "aws", + "cloud.region": "{{region}}", + "cloud.account.id": "{{accountId}}", + "cloud.platform": "aws_ec2" + } + }, + "attributes": { + "aws.local.service": "{{serviceName}}", + "aws.local.environment": "ec2:default", + "aws.local.operation": "GET remote-service", + "aws.span.kind": "LOCAL_ROOT", + "http.route": "remote-service", + "http.request.method": "GET", + "PlatformType": "AWS::EC2" + } +}, +{ + "name": "GET", + "kind": "CLIENT", + "resource": { + "attributes": { + "aws.local.service": "{{serviceName}}", + "service.name": "{{serviceName}}", + "cloud.provider": "aws", + "cloud.region": "{{region}}", + "cloud.account.id": "{{accountId}}", + "cloud.platform": "aws_ec2" + } + }, + "attributes": { + "aws.local.service": "{{serviceName}}", + "aws.local.operation": "UnmappedOperation", + "aws.remote.service": "{{remoteServiceDeploymentName}}", + "aws.remote.operation": "GET /healthcheck", + "aws.local.environment": "ec2:default", + "aws.span.kind": "CLIENT", + "url.full": "http://{{remoteServiceDeploymentName}}/healthcheck", + "http.request.method": "GET", + "PlatformType": "AWS::EC2" + } +}] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-metric.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-metric.mustache new file mode 100644 index 000000000..0d3714f71 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-metric.mustache @@ -0,0 +1,326 @@ +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: ec2:default + - + name: Operation + value: GET healthcheck + - + name: Service + value: {{remoteServiceName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{remoteServiceName}} + - + name: Environment + value: ec2:default + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Latency + namespace: {{metricNamespace}} + dimensions: + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: ec2:default + - + name: Operation + value: GET healthcheck + - + name: Service + value: {{remoteServiceName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{remoteServiceName}} + - + name: Environment + value: ec2:default + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Error + namespace: {{metricNamespace}} + dimensions: + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: GET remote-service + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Operation + value: UnmappedOperation + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Environment + value: ec2:default + - + name: Operation + value: GET healthcheck + - + name: Service + value: {{remoteServiceName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{remoteServiceName}} + - + name: Environment + value: ec2:default + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: Service + value: {{serviceName}} + - + name: Environment + value: ec2:default + - + name: RemoteOperation + value: GET /healthcheck + - + name: RemoteService + value: {{remoteServiceDeploymentName}} + +- + metricName: Fault + namespace: {{metricNamespace}} + dimensions: + - + name: RemoteService + value: {{remoteServiceDeploymentName}} diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache new file mode 100644 index 000000000..e56772553 --- /dev/null +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache @@ -0,0 +1,72 @@ +[{ + "name": "^{{serviceName}}$", + "http": { + "request": { + "url": "^{{endpoint}}/remote-service\\?ip=(([0-9]{1,3}.){3}[0-9]{1,3})&testingId={{testingId}}$", + "method": "^GET$" + }, + "response": { + "status": "^200$" + } + }, + "aws": { + "ec2": { + "instance_id": "^{{instanceId}}$" + }, + "span.kind": "^LOCAL_ROOT$" + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^GET remote-service$", + "aws.local.environment": "^ec2:default$", + "span.name": "^GET remote-service$", + "span.kind": "^SERVER$" + }, + "metadata": { + "http.url": "^{{endpoint}}/remote-service\\?ip=(([0-9]{1,3}.){3}[0-9]{1,3})&testingId={{testingId}}$", + "http.method": "^GET$", + "http.route": "^remote-service$", + "service.name": "^{{serviceName}}$", + "cloud.provider": "^aws$", + "cloud.account.id": "^{{accountId}}$", + "cloud.region": "^{{region}}$", + "cloud.platform": "^aws_ec2$", + "PlatformType": "^AWS::EC2$" + }, + "subsegments": [ + { + "name": "^{{remoteServiceDeploymentName}}$", + "http": { + "request": { + "url": "^http://{{remoteServiceDeploymentName}}/healthcheck$", + "method": "^GET$" + } + }, + "annotations": { + "aws.local.service": "^{{serviceName}}$", + "aws.local.operation": "^UnmappedOperation$", + "aws.remote.service": "^{{remoteServiceDeploymentName}}$", + "aws.remote.operation": "^GET /healthcheck$", + "aws.local.environment": "^ec2:default$", + "span.name": "^GET$", + "span.kind": "^CLIENT$" + }, + "namespace": "^remote$" + } + ] +}, +{ + "name": "^{{remoteServiceName}}$", + "http": { + "request": { + "url": "^http://{{remoteServiceDeploymentName}}/healthcheck$", + "method": "^GET$" + } + }, + "annotations": { + "aws.local.service": "^{{remoteServiceName}}$", + "aws.local.operation": "^GET healthcheck$" + } +}] + + diff --git a/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/log-validation.yml b/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/log-validation.yml new file mode 100644 index 000000000..3e5056845 --- /dev/null +++ b/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/log-validation.yml @@ -0,0 +1,25 @@ +- + validationType: "cw-log" + httpPath: "outgoing-http-call" + httpMethod: "get" + callingType: "http" + expectedLogStructureTemplate: "DOTNET_EC2_ADOT_SIGV4_OUTGOING_HTTP_CALL_LOG" +- + validationType: "cw-log" + httpPath: "aws-sdk-call" + httpMethod: "get" + callingType: "http-with-query" + expectedLogStructureTemplate: "DOTNET_EC2_ADOT_SIGV4_AWS_SDK_CALL_LOG" +- + validationType: "cw-log" + httpPath: "remote-service" + httpMethod: "get" + callingType: "http-with-query" + expectedLogStructureTemplate: "DOTNET_EC2_ADOT_SIGV4_REMOTE_SERVICE_LOG" +- + validationType: "cw-log" + httpPath: "client-call" + httpMethod: "get" + callingType: "http" + expectedLogStructureTemplate: "DOTNET_EC2_ADOT_SIGV4_CLIENT_CALL_LOG" + diff --git a/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/metric-validation.yml b/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/metric-validation.yml new file mode 100644 index 000000000..c8e0e770a --- /dev/null +++ b/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/metric-validation.yml @@ -0,0 +1,25 @@ +- + validationType: "cw-metric" + httpPath: "outgoing-http-call" + httpMethod: "get" + callingType: "http" + expectedMetricTemplate: "DOTNET_EC2_ADOT_SIGV4_OUTGOING_HTTP_CALL_METRIC" +- + validationType: "cw-metric" + httpPath: "aws-sdk-call" + httpMethod: "get" + callingType: "http-with-query" + expectedMetricTemplate: "DOTNET_EC2_ADOT_SIGV4_AWS_SDK_CALL_METRIC" +- + validationType: "cw-metric" + httpPath: "remote-service" + httpMethod: "get" + callingType: "http-with-query" + expectedMetricTemplate: "DOTNET_EC2_ADOT_SIGV4_REMOTE_SERVICE_METRIC" +- + validationType: "cw-metric" + httpPath: "client-call" + httpMethod: "get" + callingType: "http" + expectedMetricTemplate: "DOTNET_EC2_ADOT_SIGV4_CLIENT_CALL_METRIC" + diff --git a/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/trace-validation.yml b/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/trace-validation.yml new file mode 100644 index 000000000..a0b601a2a --- /dev/null +++ b/validator/src/main/resources/validations/dotnet/ec2/adot-sigv4/trace-validation.yml @@ -0,0 +1,24 @@ +- + validationType: "trace" + httpPath: "outgoing-http-call" + httpMethod: "get" + callingType: "http" + expectedTraceTemplate: "DOTNET_EC2_ADOT_SIGV4_OUTGOING_HTTP_CALL_TRACE" +- + validationType: "trace" + httpPath: "aws-sdk-call" + httpMethod: "get" + callingType: "http-with-query" + expectedTraceTemplate: "DOTNET_EC2_ADOT_SIGV4_AWS_SDK_CALL_TRACE" +- + validationType: "trace" + httpPath: "remote-service" + httpMethod: "get" + callingType: "http-with-query" + expectedTraceTemplate: "DOTNET_EC2_ADOT_SIGV4_REMOTE_SERVICE_TRACE" +- + validationType: "trace" + httpPath: "client-call" + httpMethod: "get" + callingType: "http" + expectedTraceTemplate: "DOTNET_EC2_ADOT_SIGV4_CLIENT_CALL_TRACE" \ No newline at end of file From ffe112ae9816fff5636f68fd4227d824f140d0a9 Mon Sep 17 00:00:00 2001 From: Mahad Janjua Date: Tue, 18 Mar 2025 15:44:00 -0700 Subject: [PATCH 2/3] Trace validation modifications --- terraform/dotnet/ec2/adot-sigv4/main.tf | 4 ++-- .../ec2/adot-sigv4/aws-sdk-call-trace.mustache | 13 ++++++------- .../ec2/adot-sigv4/client-call-trace.mustache | 13 ++++++------- .../adot-sigv4/outgoing-http-call-trace.mustache | 12 +++++------- .../ec2/adot-sigv4/remote-service-trace.mustache | 9 ++------- 5 files changed, 21 insertions(+), 30 deletions(-) diff --git a/terraform/dotnet/ec2/adot-sigv4/main.tf b/terraform/dotnet/ec2/adot-sigv4/main.tf index 9bb39d755..cda6608f1 100644 --- a/terraform/dotnet/ec2/adot-sigv4/main.tf +++ b/terraform/dotnet/ec2/adot-sigv4/main.tf @@ -150,7 +150,7 @@ resource "null_resource" "main_service_setup" { OTEL_TRACES_EXPORTER=none \ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://xray.${var.aws_region}.amazonaws.com/v1/traces \ OTEL_AWS_SIG_V4_ENABLED=true \ - OTEL_TRACES_SAMPLER=xray \ + OTEL_TRACES_SAMPLER=always_on \ OTEL_RESOURCE_ATTRIBUTES=service.name=dotnet-sample-application-${var.test_id} \ ASPNETCORE_URLS=http://0.0.0.0:8080 \ nohup dotnet bin/Debug/netcoreapp${var.language_version}/asp_frontend_service.dll &> nohup.out & @@ -252,7 +252,7 @@ resource "null_resource" "remote_service_setup" { OTEL_TRACES_EXPORTER=none \ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://xray.${var.aws_region}.amazonaws.com/v1/traces \ OTEL_AWS_SIG_V4_ENABLED=true \ - OTEL_TRACES_SAMPLER=xray \ + OTEL_TRACES_SAMPLER=always_on \ OTEL_RESOURCE_ATTRIBUTES=service.name=dotnet-sample-remote-application-${var.test_id} \ ASPNETCORE_URLS=http://0.0.0.0:8081 \ nohup dotnet bin/Debug/netcoreapp${var.language_version}/asp_remote_service.dll &> nohup.out & diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache index b38dccc35..a24e147d9 100644 --- a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/aws-sdk-call-trace.mustache @@ -2,7 +2,6 @@ "name": "^{{serviceName}}$", "http": { "request": { - "url": "^{{endpoint}}/aws-sdk-call\\?ip=(([0-9]{1,3}.){3}[0-9]{1,3})&testingId={{testingId}}$", "method": "^GET$" } }, @@ -20,8 +19,8 @@ "span.kind": "^SERVER$" }, "metadata": { - "http.url": "^{{endpoint}}/aws-sdk-call\\?ip=(([0-9]{1,3}.){3}[0-9]{1,3})&testingId={{testingId}}$", - "http.method": "^GET$", + "url.query": "^\\?ip=Redacted&testingId=Redacted$", + "http.request.method": "^GET$", "http.route": "^aws-sdk-call$", "service.name": "^{{serviceName}}$", "cloud.provider": "^aws$", @@ -34,8 +33,8 @@ { "name": "^S3$", "aws": { - "bucket_name": "^e2e-test-bucket-name-{{testingId}}$", - "s3.bucket": "^e2e-test-bucket-name-{{testingId}}$", + "bucket_name": "^{{testingId}}$", + "s3.bucket": "^{{testingId}}$", "span.kind": "^CLIENT$" }, "annotations": { @@ -54,8 +53,8 @@ { "name": "^S3$", "aws": { - "bucket_name": "^e2e-test-bucket-name-{{testingId}}$", - "s3.bucket": "^e2e-test-bucket-name-{{testingId}}$", + "bucket_name": "^{{testingId}}$", + "s3.bucket": "^{{testingId}}$", "span.kind": "^CLIENT$" }, "annotations": { diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache index 261cfbac2..5681d1868 100644 --- a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/client-call-trace.mustache @@ -21,10 +21,9 @@ }, "subsegments": [ { - "name": "^local-root-client-call$", + "name": "^local-root-client-call:80$", "http": { "request": { - "url": "^http://local-root-client-call/$", "method": "^GET$" } }, @@ -37,7 +36,7 @@ "annotations": { "aws.local.service": "^{{serviceName}}$", "aws.local.operation": "^InternalOperation$", - "aws.remote.service": "^local-root-client-call$", + "aws.remote.service": "^local-root-client-call:80$", "aws.remote.operation": "GET /", "aws.local.environment": "^ec2:default$", "span.name": "^GET$", @@ -45,8 +44,8 @@ }, "metadata": { "service.name": "^{{serviceName}}$", - "http.url": "^http://local-root-client-call/$", - "http.method": "^GET$", + "url.full": "^http://local-root-client-call/$", + "http.request.method": "^GET$", "cloud.provider": "^aws$", "cloud.account.id": "^{{accountId}}$", "cloud.region": "^{{region}}$", @@ -57,7 +56,7 @@ ] }, { - "name": "^local-root-client-call$", + "name": "^local-root-client-call:80$", "http": { "request": { "url": "^http://local-root-client-call/$", @@ -65,7 +64,7 @@ } }, "annotations": { - "aws.local.service": "^local-root-client-call$", + "aws.local.service": "^local-root-client-call:80$", "aws.local.operation": "^GET /$" } }] \ No newline at end of file diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache index 831649e19..d9f44e2b4 100644 --- a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/outgoing-http-call-trace.mustache @@ -2,7 +2,6 @@ "name": "^{{serviceName}}$", "http": { "request": { - "url": "^{{endpoint}}/outgoing-http-call$", "method": "^GET$" } }, @@ -20,8 +19,7 @@ "span.kind": "^SERVER$" }, "metadata": { - "http.url": "^{{endpoint}}/outgoing-http-call$", - "http.method": "^GET$", + "http.request.method": "^GET$", "http.route": "^outgoing-http-call$", "service.name": "^{{serviceName}}$", "cloud.provider": "^aws$", @@ -32,17 +30,17 @@ }, "subsegments": [ { - "name": "^www.amazon.com$", + "name": "^aws.amazon.com:443$", "http": { "request": { - "url": "^https://www.amazon.com/$", + "url": "^https://aws.amazon.com/$", "method": "^GET$" } }, "annotations": { "aws.local.service": "^{{serviceName}}$", "aws.local.operation": "^UnmappedOperation$", - "aws.remote.service": "^www.amazon.com$", + "aws.remote.service": "^aws.amazon.com:443$", "aws.remote.operation": "^GET /$", "aws.local.environment": "^ec2:default$", "span.name": "^GET$", @@ -53,5 +51,5 @@ ] }, { - "name": "^www.amazon.com$" + "name": "^aws.amazon.com:443$" }] diff --git a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache index e56772553..1e304d6c1 100644 --- a/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache +++ b/validator/src/main/resources/expected-data-template/dotnet/ec2/adot-sigv4/remote-service-trace.mustache @@ -2,11 +2,7 @@ "name": "^{{serviceName}}$", "http": { "request": { - "url": "^{{endpoint}}/remote-service\\?ip=(([0-9]{1,3}.){3}[0-9]{1,3})&testingId={{testingId}}$", "method": "^GET$" - }, - "response": { - "status": "^200$" } }, "aws": { @@ -23,8 +19,8 @@ "span.kind": "^SERVER$" }, "metadata": { - "http.url": "^{{endpoint}}/remote-service\\?ip=(([0-9]{1,3}.){3}[0-9]{1,3})&testingId={{testingId}}$", - "http.method": "^GET$", + "url.query": "^\\?ip=Redacted&testingId=Redacted$", + "http.request.method": "^GET$", "http.route": "^remote-service$", "service.name": "^{{serviceName}}$", "cloud.provider": "^aws$", @@ -59,7 +55,6 @@ "name": "^{{remoteServiceName}}$", "http": { "request": { - "url": "^http://{{remoteServiceDeploymentName}}/healthcheck$", "method": "^GET$" } }, From aff552c3a1a4b25b4d2f9bad7e5ec6176b0297cc Mon Sep 17 00:00:00 2001 From: Mahad Janjua Date: Tue, 18 Mar 2025 16:44:20 -0700 Subject: [PATCH 3/3] Prepare for merge, remove code used to test changes --- .../workflows/dotnet-ec2-adot-sigv4-test.yml | 15 ++++++------ .github/workflows/test.yml | 24 ------------------- 2 files changed, 7 insertions(+), 32 deletions(-) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/dotnet-ec2-adot-sigv4-test.yml b/.github/workflows/dotnet-ec2-adot-sigv4-test.yml index 100412697..5adb4b77f 100644 --- a/.github/workflows/dotnet-ec2-adot-sigv4-test.yml +++ b/.github/workflows/dotnet-ec2-adot-sigv4-test.yml @@ -71,14 +71,13 @@ jobs: - name: Set Get ADOT Distro command environment variable run: | - echo GET_ADOT_DISTRO_COMMAND="aws s3 cp s3://adot-autoinstrumentation-dotnet-staging/${{ env.ADOT_DISTRO_NAME }} ./${{ env.ADOT_DISTRO_NAME }} && unzip -d dotnet-distro ${{ env.ADOT_DISTRO_NAME }}" >> $GITHUB_ENV - # if [ "${{ github.event.repository.name }}" = "aws-otel-dotnet-instrumentation" ]; then - # # Get staging distro file from staging bucket - # echo GET_ADOT_DISTRO_COMMAND="aws s3 cp s3://adot-autoinstrumentation-dotnet-staging/${{ env.ADOT_DISTRO_NAME }} ./${{ env.ADOT_DISTRO_NAME }} && unzip -d dotnet-distro ${{ env.ADOT_DISTRO_NAME }}" >> $GITHUB_ENV - # else - # # After Release will switch to latest tag instead of hard code version for canary purpose - # echo GET_ADOT_DISTRO_COMMAND="wget -O aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip https://github.com/aws-observability/aws-otel-dotnet-instrumentation/releases/latest/download/aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip && unzip -d dotnet-distro aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip" >> $GITHUB_ENV - # fi + if [ "${{ github.event.repository.name }}" = "aws-otel-dotnet-instrumentation" ]; then + # Get staging distro file from staging bucket + echo GET_ADOT_DISTRO_COMMAND="aws s3 cp s3://adot-autoinstrumentation-dotnet-staging/${{ env.ADOT_DISTRO_NAME }} ./${{ env.ADOT_DISTRO_NAME }} && unzip -d dotnet-distro ${{ env.ADOT_DISTRO_NAME }}" >> $GITHUB_ENV + else + # After Release will switch to latest tag instead of hard code version for canary purpose + echo GET_ADOT_DISTRO_COMMAND="wget -O aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip https://github.com/aws-observability/aws-otel-dotnet-instrumentation/releases/latest/download/aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip && unzip -d dotnet-distro aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip" >> $GITHUB_ENV + fi - name: Set up terraform uses: ./.github/workflows/actions/execute_and_retry diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 03ad88c6a..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,24 +0,0 @@ -## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -## SPDX-License-Identifier: Apache-2.0 - -# This is a reusable workflow for running the Enablement test for App Signals. -# It is meant to be called from another workflow. -# Read more about reusable workflows: https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview -name: Test -on: - push: - branches: - - dotnet-sigv4 - -permissions: - id-token: write - contents: read - -jobs: - # Runs in us-west-1 using us-east-1 account - dotnet-ec2-adot-sigv4: - uses: ./.github/workflows/dotnet-ec2-adot-sigv4-test.yml - secrets: inherit - with: - caller-workflow-name: 'test' - staging_distro_name: 'aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip' \ No newline at end of file