Skip to content

Commit aaa4b32

Browse files
authored
Merge branch 'main' into add-checksum
2 parents 61944cf + 73c8137 commit aaa4b32

38 files changed

+1885
-66
lines changed

.github/workflows/application-signals-e2e-test.yml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ jobs:
5959
6060
upload-main-build-image:
6161
runs-on: ${{ matrix.os }}
62+
outputs:
63+
short_sha: ${{ steps.short_sha.outputs.SHORT_SHA }}
6264
continue-on-error: true
6365
strategy:
6466
matrix:
@@ -67,7 +69,13 @@ jobs:
6769
- os: ubuntu-latest
6870
steps:
6971
- uses: actions/checkout@v3
70-
72+
- name: Get Short SHA
73+
id: short_sha
74+
run: |
75+
shortsha="$(git rev-parse --short HEAD)"
76+
echo "SHORT_SHA=$shortsha" >> $GITHUB_OUTPUT
77+
shell: bash
78+
7179
- name: Configure AWS credentials for private ECR
7280
uses: aws-actions/configure-aws-credentials@v4
7381
with:
@@ -108,14 +116,14 @@ jobs:
108116
if: runner.os == 'Linux'
109117
run: |
110118
set -e
111-
docker build -t ${{ secrets.RELEASE_STAIGNG_REPO }}:staging-linux-amd64 -f ./Dockerfile.linux .
112-
docker push ${{ secrets.RELEASE_STAIGNG_REPO }}:staging-linux-amd64
119+
docker build -t ${{ secrets.RELEASE_STAIGNG_REPO }}:staging-linux-amd64-${{ steps.short_sha.outputs.SHORT_SHA }} -f ./Dockerfile.linux .
120+
docker push ${{ secrets.RELEASE_STAIGNG_REPO }}:staging-linux-amd64-${{ steps.short_sha.outputs.SHORT_SHA }}
113121
114122
- name: Build Windows container
115123
if: runner.os == 'Windows'
116124
run: |
117-
docker build -t ${{ secrets.RELEASE_STAIGNG_REPO }}:staging-windows2022 -f ./Dockerfile.windows2022 .
118-
docker push ${{ secrets.RELEASE_STAIGNG_REPO }}:staging-windows2022
125+
docker build -t ${{ secrets.RELEASE_STAIGNG_REPO }}:staging-windows2022-${{ steps.short_sha.outputs.SHORT_SHA }} -f ./Dockerfile.windows2022 .
126+
docker push ${{ secrets.RELEASE_STAIGNG_REPO }}:staging-windows2022-${{ steps.short_sha.outputs.SHORT_SHA }}
119127
shell: powershell
120128

121129
dotnet-ec2-default-test:
@@ -141,7 +149,7 @@ jobs:
141149
uses: aws-observability/aws-application-signals-test-framework/.github/workflows/dotnet-eks-test.yml@main
142150
secrets: inherit
143151
with:
144-
adot-image-name: ${{ inputs.adot-linux-image-name }}
152+
adot-image-name: ${{ inputs.adot-linux-image-name }}-${{ needs.upload-main-build-image.outputs.short_sha }}
145153
aws-region: us-east-1
146154
test-cluster-name: 'e2e-dotnet-adot-test'
147155
caller-workflow-name: 'main-build'
@@ -151,7 +159,7 @@ jobs:
151159
uses: aws-observability/aws-application-signals-test-framework/.github/workflows/dotnet-eks-windows-test.yml@main
152160
secrets: inherit
153161
with:
154-
adot-image-name: ${{ inputs.adot-windows-image-name }}
162+
adot-image-name: ${{ inputs.adot-windows-image-name }}-${{ needs.upload-main-build-image.outputs.short_sha }}
155163
aws-region: us-east-1
156164
test-cluster-name: 'eks-windows-manual'
157165
caller-workflow-name: 'main-build'

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,4 +467,9 @@ lychee/out.md
467467
*/dist
468468

469469
# Python cache
470-
*.pytest_cache
470+
*.pytest_cache
471+
472+
# Terraform files
473+
.terraform*
474+
terraform.tfstate
475+
terraform.tfstate.backup

AWS.Distro.OpenTelemetry.AutoInstrumentation.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MockCollector", "test\image
4343
EndProject
4444
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.AWS", "src\OpenTelemetry.Instrumentation.AWS\OpenTelemetry.Instrumentation.AWS.csproj", "{30B39779-F7AA-4AAB-B3AB-A0EFEEC35CED}"
4545
EndProject
46+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleLambdaFunction", "sample-applications\lambda-test-apps\SimpleLambdaFunction\src\SimpleLambdaFunction\SimpleLambdaFunction.csproj", "{3E5D9A9C-5280-4061-9B6A-5E2FDAF6FE49}"
47+
EndProject
4648
Global
4749
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4850
Debug|Any CPU = Debug|Any CPU
@@ -69,6 +71,10 @@ Global
6971
{30B39779-F7AA-4AAB-B3AB-A0EFEEC35CED}.Debug|Any CPU.Build.0 = Debug|Any CPU
7072
{30B39779-F7AA-4AAB-B3AB-A0EFEEC35CED}.Release|Any CPU.ActiveCfg = Release|Any CPU
7173
{30B39779-F7AA-4AAB-B3AB-A0EFEEC35CED}.Release|Any CPU.Build.0 = Release|Any CPU
74+
{3E5D9A9C-5280-4061-9B6A-5E2FDAF6FE49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
75+
{3E5D9A9C-5280-4061-9B6A-5E2FDAF6FE49}.Debug|Any CPU.Build.0 = Debug|Any CPU
76+
{3E5D9A9C-5280-4061-9B6A-5E2FDAF6FE49}.Release|Any CPU.ActiveCfg = Release|Any CPU
77+
{3E5D9A9C-5280-4061-9B6A-5E2FDAF6FE49}.Release|Any CPU.Build.0 = Release|Any CPU
7278
EndGlobalSection
7379
GlobalSection(SolutionProperties) = preSolution
7480
HideSolutionNode = FALSE
@@ -81,5 +87,6 @@ Global
8187
{E3401B0D-DCE1-45C2-8178-2D21FA52F659} = {DD015346-5FF7-4298-AD31-326B18040908}
8288
{ECD2F534-A9FB-48B4-8C06-6DD2F8B07C41} = {E3401B0D-DCE1-45C2-8178-2D21FA52F659}
8389
{30B39779-F7AA-4AAB-B3AB-A0EFEEC35CED} = {BDFD4285-9DB0-4F47-8EDC-7F32A781DCD4}
90+
{3E5D9A9C-5280-4061-9B6A-5E2FDAF6FE49} = {7E420F1D-B6D6-47AF-A430-5368FE14D2AA}
8491
EndGlobalSection
8592
EndGlobal

build/Build.InstallationScripts.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
internal partial class Build : NukeBuild
99
{
1010
private readonly AbsolutePath installationScriptsFolder = RootDirectory / "bin" / "InstallationScripts";
11-
private readonly string version = "1.3.2.dev0";
11+
private readonly string version = "1.4.0.dev0";
1212

1313
public Target BuildInstallationScripts => _ => _
1414
.After(this.Clean)

instrument.sh

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ case "$ENABLE_PROFILING" in
7070
;;
7171
esac
7272

73+
if [ ! -z "${AWS_LAMBDA_FUNCTION_NAME}" ]; then
74+
OTEL_DOTNET_AUTO_HOME="/opt"
75+
fi
76+
7377
# set defaults
7478
test -z "$OTEL_DOTNET_AUTO_HOME" && OTEL_DOTNET_AUTO_HOME="$HOME/.otel-dotnet-auto"
7579

@@ -173,13 +177,61 @@ if [ "$ENABLE_PROFILING" = "true" ]; then
173177

174178
# AWS OTEL DOTNET
175179
export OTEL_DOTNET_AUTO_PLUGINS="AWS.Distro.OpenTelemetry.AutoInstrumentation.Plugin, AWS.Distro.OpenTelemetry.AutoInstrumentation"
176-
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
177-
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4316"
178-
export OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT="http://127.0.0.1:4316/v1/metrics"
179-
export OTEL_METRICS_EXPORTER="none"
180-
export OTEL_AWS_APPLICATION_SIGNALS_ENABLED="true"
181-
export OTEL_TRACES_SAMPLER="xray"
182-
export OTEL_TRACES_SAMPLER_ARG="endpoint=http://127.0.0.1:2000"
180+
181+
# If this is true, that means we are in a lambda env. In this case, setup the environment for lambda.
182+
if [ ! -z "${AWS_LAMBDA_FUNCTION_NAME}" ]; then
183+
184+
export OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER="$_HANDLER"
185+
export _HANDLER="AWS.Distro.OpenTelemetry.AutoInstrumentation::AWS.Distro.OpenTelemetry.AutoInstrumentation.LambdaWrapper::TracingFunctionHandler"
186+
187+
echo "$DOTNET_SHARED_STORE"
188+
189+
if [ -z "${OTEL_EXPORTER_OTLP_PROTOCOL}" ]; then
190+
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
191+
fi
192+
193+
if [ -z "${OTEL_SERVICE_NAME}" ]; then
194+
export OTEL_SERVICE_NAME=$AWS_LAMBDA_FUNCTION_NAME;
195+
fi
196+
197+
export LAMBDA_RESOURCE_ATTRIBUTES="cloud.region=$AWS_REGION,cloud.provider=aws,faas.name=$AWS_LAMBDA_FUNCTION_NAME,faas.version=$AWS_LAMBDA_FUNCTION_VERSION,faas.instance=$AWS_LAMBDA_LOG_STREAM_NAME,aws.log.group.names=$AWS_LAMBDA_LOG_GROUP_NAME";
198+
199+
if [ -z "${OTEL_AWS_APPLICATION_SIGNALS_ENABLED}" ]; then
200+
export OTEL_AWS_APPLICATION_SIGNALS_ENABLED="true";
201+
fi
202+
203+
if [ -z "${OTEL_METRICS_EXPORTER}" ]; then
204+
export OTEL_METRICS_EXPORTER="none";
205+
fi
206+
207+
if [ -z "${OTEL_RESOURCE_ATTRIBUTES}" ]; then
208+
export OTEL_RESOURCE_ATTRIBUTES=$LAMBDA_RESOURCE_ATTRIBUTES;
209+
else
210+
export OTEL_RESOURCE_ATTRIBUTES="$LAMBDA_RESOURCE_ATTRIBUTES,$OTEL_RESOURCE_ATTRIBUTES";
211+
fi
212+
213+
if [ -z "${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT}" ] && [ -z "${OTEL_EXPORTER_OTLP_ENDPOINT}" ]; then
214+
export OTEL_TRACES_EXPORTER="none";
215+
fi
216+
217+
# TODO: need to disable all instrumentations except aws sdk and lambda.
218+
219+
else
220+
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
221+
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4316"
222+
export OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT="http://127.0.0.1:4316/v1/metrics"
223+
export OTEL_METRICS_EXPORTER="none"
224+
export OTEL_AWS_APPLICATION_SIGNALS_ENABLED="true"
225+
export OTEL_TRACES_SAMPLER="xray"
226+
export OTEL_TRACES_SAMPLER_ARG="endpoint=http://127.0.0.1:2000"
227+
fi
228+
183229
fi
184230

185-
exec "$@"
231+
# in a lambda env, we need to change the handler in the exec command to the lambda wrapper
232+
# else, we pass the execution back to the main caller unchanged.
233+
if [ ! -z "${AWS_LAMBDA_FUNCTION_NAME}" ]; then
234+
exec "${@//$OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER/$_HANDLER}"
235+
else
236+
exec "$@"
237+
fi
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# AWS Lambda Application Signals Support
2+
3+
This package provides support for **Application Signals** in AWS Lambda environment.
4+
5+
## Features
6+
7+
- Supports Application Signals, including traces and metrics, for AWS Lambda .NET Runtimes.
8+
- Automates the deployment process, including the creation of the Application .NET Lambda Layer and a sample Lambda function.
9+
10+
## Prerequisites
11+
12+
Before you begin, make sure you have installed and configured the following tools:
13+
14+
- [Docker](https://www.docker.com/get-started)
15+
- [Terraform](https://www.terraform.io/downloads)
16+
- [AWS CLI](https://aws.amazon.com/cli/) (to configure AWS credentials)
17+
- [.NET Lambda Tools](https://docs.aws.amazon.com/lambda/latest/dg/csharp-package-cli.html) (to build and publish lambda function)
18+
19+
### Configure AWS Credentials
20+
21+
Ensure that your AWS credentials are properly configured in your local environment. You can use the following command with the AWS CLI:
22+
23+
```bash
24+
aws configure
25+
```
26+
This will prompt you to enter your `AWS Access Key ID`, `AWS Secret Access Key`, `Default region name`, and `Default output format`.
27+
28+
## Installation and Deployment
29+
30+
### 1. Clone the Repository
31+
32+
First, clone this repository to your local machine:
33+
34+
```bash
35+
git clone https://github.com/aws-observability/aws-otel-dotnet-instrumentation.git
36+
```
37+
38+
### 2. Run the Build Script
39+
40+
Navigate to the `lambda-test-apps` folder and run the `build-and-deploy.sh` script. This will create the Application .NET Lambda Layer and a Lambda sample app in your AWS account:
41+
42+
```bash
43+
cd sample-applications/lambda-test-apps/SimpleLambdaFunction/
44+
./build-and-deploy.sh
45+
```
46+
47+
## Lambda Sample App
48+
49+
Once the script has successfully run, you will see the deployed Lambda sample app in your AWS account. You can trigger the
50+
Lambda function and view the traces and metrics through the AWS CloudWatch Console.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
check_if_step_failed_and_exit() {
6+
if [ $? -ne 0 ]; then
7+
echo $1
8+
exit 1
9+
fi
10+
}
11+
12+
# Build the distro
13+
cd ../../../
14+
bash ./build.sh
15+
check_if_step_failed_and_exit "There was an error building AWS Otel DotNet, exiting"
16+
17+
cd ./sample-applications/lambda-test-apps/SimpleLambdaFunction
18+
dotnet lambda package -pl ./src/SimpleLambdaFunction
19+
check_if_step_failed_and_exit "There was an error building the SimpleLambdaFunction, exiting"
20+
21+
cd ./terraform/lambda
22+
terraform init
23+
terraform apply -auto-approve
24+
check_if_step_failed_and_exit "There was an error deploying the SimpleLambdaFunction, exiting"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using Amazon.Lambda.Core;
2+
using Amazon.Lambda.APIGatewayEvents;
3+
using Amazon.S3;
4+
5+
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
6+
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
7+
8+
namespace SimpleLambdaFunction;
9+
10+
public class Function
11+
{
12+
private static readonly HttpClient httpClient = new HttpClient();
13+
private static readonly AmazonS3Client s3Client = new AmazonS3Client();
14+
15+
/// <summary>
16+
/// This function handles API Gateway requests and returns results from an HTTP request and S3 call.
17+
/// </summary>
18+
/// <param name="apigProxyEvent"></param>
19+
/// <param name="context"></param>
20+
/// <returns></returns>
21+
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
22+
{
23+
context.Logger.LogLine("Making HTTP call to https://aws.amazon.com/");
24+
await httpClient.GetAsync("https://aws.amazon.com/");
25+
26+
context.Logger.LogLine("Making AWS S3 ListBuckets call");
27+
int bucketCount = await ListS3Buckets().ConfigureAwait(false);
28+
29+
var traceId = Environment.GetEnvironmentVariable("_X_AMZN_TRACE_ID");
30+
31+
return new APIGatewayProxyResponse
32+
{
33+
StatusCode = 200,
34+
Body = $"Hello lambda - found {bucketCount} buckets. X-Ray Trace ID: {traceId}",
35+
Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }
36+
};
37+
}
38+
39+
/// <summary>
40+
/// List all S3 buckets using AWS SDK for .NET
41+
/// </summary>
42+
/// <returns>Number of buckets available</returns>
43+
private async Task<int> ListS3Buckets()
44+
{
45+
var response = await s3Client.ListBucketsAsync();
46+
return response.Buckets.Count;
47+
}
48+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# AWS Lambda Empty Function Project
2+
3+
This starter project consists of:
4+
* Function.cs - class file containing a class with a single function handler method
5+
* aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS
6+
7+
You may also have a test project depending on the options selected.
8+
9+
The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs.
10+
11+
## Here are some steps to follow from Visual Studio:
12+
13+
To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*.
14+
15+
To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree.
16+
17+
To perform testing against your deployed function use the Test Invoke tab in the opened Function View window.
18+
19+
To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window.
20+
21+
To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window.
22+
23+
To view execution logs of invocations of your function use the Logs tab in the opened Function View window.
24+
25+
## Here are some steps to follow to get started from the command line:
26+
27+
Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line.
28+
29+
Install Amazon.Lambda.Tools Global Tools if not already installed.
30+
```
31+
dotnet tool install -g Amazon.Lambda.Tools
32+
```
33+
34+
If already installed check if new version is available.
35+
```
36+
dotnet tool update -g Amazon.Lambda.Tools
37+
```
38+
39+
Execute unit tests
40+
```
41+
cd "SimpleLambdaFunction/test/SimpleLambdaFunction.Tests"
42+
dotnet test
43+
```
44+
45+
Deploy function to AWS Lambda
46+
```
47+
cd "SimpleLambdaFunction/src/SimpleLambdaFunction"
48+
dotnet lambda deploy-function
49+
```
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<ImplicitUsings>enable</ImplicitUsings>
5+
<Nullable>enable</Nullable>
6+
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
7+
<AWSProjectType>Lambda</AWSProjectType>
8+
<!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. -->
9+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
10+
<!-- Generate ready to run images during publishing to improve cold start time. -->
11+
<PublishReadyToRun>true</PublishReadyToRun>
12+
</PropertyGroup>
13+
<ItemGroup>
14+
<PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.7.1" />
15+
<PackageReference Include="Amazon.Lambda.Core" Version="2.2.0" />
16+
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.4.1" />
17+
<PackageReference Include="AWSSDK.S3" Version="3.7.405.2" />
18+
</ItemGroup>
19+
</Project>

0 commit comments

Comments
 (0)