-
Notifications
You must be signed in to change notification settings - Fork 207
fix: NodeJS sample #1840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: NodeJS sample #1840
Changes from all commits
01cade1
c9442c2
dba7bc5
6ce50bd
90a3539
d1a29fd
a633dfa
9606fad
766d977
22c299a
26be628
10491f6
8775310
7e4244f
46d6c09
244fd1c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
build | ||
cdk.out | ||
bin | ||
lib |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,4 @@ module.exports = { | |
"node": true | ||
}, | ||
...require('../../eslint.config.js') | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cdk.out | ||
build |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,77 @@ | ||
# AWS SDK Sample Application | ||
# 🧪 AWS SDK Sample Application with OpenTelemetry | ||
|
||
**This Sample App is a work-in-progress because it depends on the OpenTelemetry public layer. The public layer will not be published | ||
This sample demonstrates how to use the **AWS SDK** within a Lambda function with **OpenTelemetry (OTel)** capabilities. It performs a simple `STS GetCallerIdentity` call for demonstration purposes and outputs Otel telemetry data to logs. | ||
|
||
This sample application demonstrates usage of the AWS SDK. To try it out, make sure the collector and nodejs Lambda | ||
layers are built. | ||
Example log output: | ||
 | ||
|
||
In [collector](../../../collector), run `make package`. | ||
In [nodejs](../../), run `npm install`. | ||
--- | ||
|
||
Then, run `terraform init` and `terraform apply`. The lambda function will be initialized and the URL for an API Gateway invoking the Lambda | ||
will be displayed at the end. Send a request to the URL in a browser or using curl to execute the function. Then, | ||
navigate to the function's logs [here](https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logStream:group=%252Faws%252Flambda%252Fhello-nodejs). | ||
You will see a log stream with an event time corresponding to when you issued the request - open it and you can find | ||
information about the exported spans in the log stream. | ||
## 🚀 Deploy Using AWS CDK | ||
|
||
Follow these steps to deploy the demo stack via CDK: | ||
|
||
1. **Install dependencies** | ||
`npm install` | ||
|
||
2. **Bootstrap your AWS environment (if not done already)** | ||
`npx cdk bootstrap` | ||
|
||
3. **Deploy the stack** | ||
`npx cdk deploy OtelSampleLambdaStack` | ||
|
||
--- | ||
|
||
## 🚀 Deploy Using Terraform | ||
|
||
Follow these steps to deploy the demo stack via Terraform: | ||
|
||
1. **Install dependencies** | ||
`npm install` | ||
|
||
2. **Build the Lambda function artifact** | ||
`npm run build` | ||
|
||
3. **Move to deploy/wrapper folder** | ||
`cd deploy/wrapper` | ||
|
||
4. **Terraform init** | ||
`terraform init` | ||
|
||
5. **Terraform apply** | ||
`terraform apply` | ||
|
||
--- | ||
|
||
## 🛠️ Manual Deployment via AWS Console | ||
|
||
If you'd prefer to deploy manually: | ||
|
||
1. **Install dependencies** | ||
`npm install` | ||
|
||
2. **Build the Lambda function artifact** | ||
`npm run build` | ||
|
||
3. **Create a new AWS Lambda function** | ||
- Runtime: Select the latest `nodejs.x` | ||
|
||
4. **Upload the artifact** | ||
- File location: `build/function.zip` | ||
|
||
5. **Set the following environment variables** | ||
``` | ||
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/ | ||
OTEL_TRACES_EXPORTER=console | ||
OTEL_METRICS_EXPORTER=console | ||
OTEL_LOG_LEVEL=INFO | ||
OTEL_TRACES_SAMPLER=always_on | ||
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-handler | ||
``` | ||
6. **Attach the Node.js instrumentation layer** | ||
- Refer to the latest ARN in the OpenTelemetry Lambda releases, ie: | ||
https://github.com/open-telemetry/opentelemetry-lambda/releases/tag/layer-nodejs%2F0.14.0 | ||
|
||
7. **Attach the OpenTelemetry Collector layer** | ||
- Refer to the ARN in the release notes, ie: | ||
https://github.com/open-telemetry/opentelemetry-lambda/releases/tag/layer-collector%2F0.15.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/usr/bin/env node | ||
import * as cdk from 'aws-cdk-lib'; | ||
import { OtelSampleLambdaStack } from '../lib/otel-sample-lambda-stack'; | ||
|
||
const app = new cdk.App(); | ||
new OtelSampleLambdaStack(app, 'OtelSampleLambdaStack'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"app": "npm run build" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,16 +4,10 @@ variable "name" { | |
default = "hello-nodejs-awssdk" | ||
} | ||
|
||
variable "collector_layer_arn" { | ||
variable "account_id" { | ||
type = string | ||
description = "ARN for the Lambda layer containing the OpenTelemetry collector extension" | ||
// TODO(anuraaga): Add default when a public layer is published. | ||
} | ||
|
||
variable "sdk_layer_arn" { | ||
type = string | ||
description = "ARN for the Lambda layer containing the OpenTelemetry NodeJS Wrapper" | ||
// TODO(anuraaga): Add default when a public layer is published. | ||
description = "AWS account ID where the Lambda layers are published" | ||
default = "184161586896" | ||
} | ||
|
||
variable "tracing_mode" { | ||
|
@@ -25,12 +19,23 @@ variable "tracing_mode" { | |
variable "architecture" { | ||
type = string | ||
description = "Lambda function architecture, valid values are arm64 or x86_64" | ||
default = "x86_64" | ||
default = "arm64" | ||
} | ||
|
||
variable "runtime" { | ||
type = string | ||
description = "NodeJS runtime version used for sample Lambda Function" | ||
default = "nodejs18.x" | ||
default = "nodejs22.x" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non blocking nit, but should we not change the node engine version in package.json as well? To There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since upgrade to v2 sdk, the sdk officially supports minimum node version of |
||
} | ||
|
||
variable "collector_layer_version" { | ||
type = string | ||
description = "Collector layer version, see latest releases here: https://github.com/open-telemetry/opentelemetry-lambda/releases" | ||
default = "0_15_0" | ||
} | ||
|
||
variable "nodejs_layer_version" { | ||
type = string | ||
description = "Node.js layer version, see latest releases here: https://github.com/open-telemetry/opentelemetry-lambda/releases" | ||
default = "0_14_0" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { | ||
APIGatewayProxyEvent, | ||
APIGatewayProxyResult, | ||
Context, | ||
} from 'aws-lambda'; | ||
|
||
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts'; | ||
|
||
const sts = new STSClient({}); | ||
|
||
export const handler = async ( | ||
event: APIGatewayProxyEvent, | ||
_context: Context, | ||
): Promise<APIGatewayProxyResult> => { | ||
console.log('Received event:', JSON.stringify(event, null, 2)); | ||
console.log('Received context:', JSON.stringify(_context, null, 2)); | ||
|
||
try { | ||
const result = await sts.send(new GetCallerIdentityCommand({})); | ||
|
||
const response: APIGatewayProxyResult = { | ||
statusCode: 200, | ||
body: JSON.stringify({ | ||
message: 'Caller identity retrieved successfully', | ||
identity: { | ||
Account: result.Account, | ||
Arn: result.Arn, | ||
UserId: result.UserId, | ||
}, | ||
}), | ||
}; | ||
return response; | ||
} catch (error) { | ||
console.error('Error retrieving caller identity:', error); | ||
return { | ||
statusCode: 500, | ||
body: 'Internal Server Error', | ||
}; | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import * as cdk from 'aws-cdk-lib'; | ||
import { Construct } from 'constructs'; | ||
import * as lambda from 'aws-cdk-lib/aws-lambda'; | ||
import * as path from 'path'; | ||
|
||
const AWS_ACCOUNT_ID = '184161586896'; // Replace with your AWS account ID if you want to use a specific layer | ||
const NODEJS_LAYER_VERSION = '0_14_0'; // Update with the latest version if needed | ||
const COLLECTOR_LAYER_VERSION = '0_15_0'; // Update with the latest version if needed | ||
|
||
export class OtelSampleLambdaStack extends cdk.Stack { | ||
constructor(scope: Construct, id: string, props?: cdk.StackProps) { | ||
super(scope, id, props); | ||
|
||
const region = cdk.Stack.of(this).region; | ||
const architecture = lambda.Architecture.ARM_64; | ||
const collectorLayerArn = `arn:aws:lambda:${region}:${AWS_ACCOUNT_ID}:layer:opentelemetry-collector-${architecture}-${COLLECTOR_LAYER_VERSION}:1`; | ||
const nodejsInstrumentationLayerArn = `arn:aws:lambda:${region}:${AWS_ACCOUNT_ID}:layer:opentelemetry-nodejs-${NODEJS_LAYER_VERSION}:1`; | ||
|
||
new lambda.Function(this, 'MyLambdaFunction', { | ||
runtime: lambda.Runtime.NODEJS_22_X, | ||
handler: 'index.handler', | ||
code: lambda.Code.fromAsset(path.join(__dirname, '../build/lambda')), | ||
layers: [ | ||
lambda.LayerVersion.fromLayerVersionArn(this, 'OtelCollectorLayer', collectorLayerArn), | ||
lambda.LayerVersion.fromLayerVersionArn(this, 'NodeJsInstrumentationLayer', nodejsInstrumentationLayerArn) | ||
], | ||
timeout: cdk.Duration.seconds(30), | ||
memorySize: 256, | ||
architecture, | ||
environment: { | ||
OTEL_EXPORTER_OTLP_ENDPOINT: 'http://localhost:4318/', | ||
OTEL_TRACES_EXPORTER: 'console', | ||
OTEL_METRICS_EXPORTER: 'console', | ||
OTEL_LOG_LEVEL: 'DEBUG', | ||
OTEL_TRACES_SAMPLER: 'always_on', | ||
AWS_LAMBDA_EXEC_WRAPPER: '/opt/otel-handler', | ||
}, | ||
}); | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,6 @@ | |
"outDir": "build" | ||
}, | ||
"include": [ | ||
"src/**/*.ts", | ||
"test/**/*.ts" | ||
"lambda/**/*.ts", | ||
] | ||
} |
Uh oh!
There was an error while loading. Please reload this page.