Skip to content

Commit 3bece0c

Browse files
authored
Refactor Lambda Layer bundling (#173)
*Issue #, if available:* *Description of changes:* #171 introduced a bug where the Lambda server span was no longer produced in trace map for ESM-based handlers. This PR fixes the bug and now bundles the lambda layer directly instead of the autoinstrumentation package. The size of the bundled layer is now ~920KB, a nearly 94% reduction in size from the original 14.5MB. The following files were copied from upstream to support Lambda layer bundling with minor changes: `webpack.config.js`, `tsconfig.webpack.json`, `tsconfig.esm.json`, and`install-externals.sh`. Trace Map for CJS handler: ![image](https://github.com/user-attachments/assets/fe319402-db2b-41c9-b28d-14c6953ac2ba) Trace Map for ESM handler: ![image](https://github.com/user-attachments/assets/d70f91f0-2c49-40b0-b3e4-4270ba39648f) Trace Map for ESM handler prior to fix (with bug): ![image](https://github.com/user-attachments/assets/fa0e5726-e485-4029-9b01-9e68cf6d7a5e) By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
1 parent 97c5fae commit 3bece0c

File tree

9 files changed

+84
-850
lines changed

9 files changed

+84
-850
lines changed

aws-distro-opentelemetry-node-autoinstrumentation/package.json

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@
2222
"repository": "aws-observability/aws-otel-js-instrumentation",
2323
"scripts": {
2424
"clean": "rimraf build/*",
25-
"compile:tsc": "tsc -p .",
26-
"compile:webpack": "webpack",
27-
"compile": "npm run compile:webpack",
25+
"compile": "tsc -p .",
2826
"lint": "eslint . --ext .ts",
2927
"lint:fix": "eslint . --ext .ts --fix",
3028
"create-version": "node -p \"'export const LIB_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
@@ -95,11 +93,8 @@
9593
"proxyquire": "^2.1.3",
9694
"rimraf": "5.0.5",
9795
"sinon": "15.2.0",
98-
"ts-loader": "^9.5.2",
9996
"ts-mocha": "10.0.0",
100-
"typescript": "4.4.4",
101-
"webpack": "^5.98.0",
102-
"webpack-cli": "^6.0.1"
97+
"typescript": "4.4.4"
10398
},
10499
"dependencies": {
105100
"@opentelemetry/api": "1.9.0",
@@ -115,7 +110,6 @@
115110
"@opentelemetry/instrumentation-aws-sdk": "0.49.0",
116111
"@opentelemetry/otlp-transformer": "0.57.1",
117112
"@opentelemetry/propagator-aws-xray": "1.26.2",
118-
"@opentelemetry/propagator-aws-xray-lambda": "^0.54.0",
119113
"@opentelemetry/resource-detector-aws": "1.12.0",
120114
"@opentelemetry/resources": "1.30.1",
121115
"@opentelemetry/sdk-metrics": "1.30.1",
@@ -127,7 +121,6 @@
127121
"build/src/**/*.js",
128122
"build/src/**/*.js.map",
129123
"build/src/**/*.d.ts",
130-
"build/src/**/*.d.ts.map",
131124
"build/src/**/*.json"
132125
]
133126
}

aws-distro-opentelemetry-node-autoinstrumentation/tsconfig.webpack.json

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
3+
set -euf -o pipefail
4+
5+
# Space separated list of external NPM packages
6+
7+
# import-in-the-middle's hook.mjs is used as a module loader for ESM-based handlers and must be available at runtime,
8+
# so we have to install it a standalone package separate from the bundled layer.
9+
EXTERNAL_PACKAGES=( "import-in-the-middle" )
10+
11+
for EXTERNAL_PACKAGE in "${EXTERNAL_PACKAGES[@]}"
12+
do
13+
echo "Installing external package $EXTERNAL_PACKAGE ..."
14+
15+
PACKAGE_VERSION=$(npm query "#$EXTERNAL_PACKAGE" \
16+
| grep version \
17+
| head -1 \
18+
| awk -F: '{ print $2 }' \
19+
| sed 's/[",]//g')
20+
21+
echo "Resolved version of the external package $EXTERNAL_PACKAGE: $PACKAGE_VERSION"
22+
23+
npm install "$EXTERNAL_PACKAGE@$PACKAGE_VERSION" --prefix ./build/workspace/nodejs --production --ignore-scripts
24+
25+
echo "Installed external package $EXTERNAL_PACKAGE"
26+
done

lambda-layer/packages/layer/package.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
},
1818
"scripts": {
1919
"clean": "rimraf build/*",
20+
"install-externals": "./install-externals.sh",
2021
"lint": "eslint . --ext .ts",
2122
"lint:fix": "eslint . --ext .ts --fix",
22-
"prepare": "npm run compile",
23-
"compile": "tsc -p .",
24-
"postcompile": "copyfiles -F 'node_modules/**' build/workspace/nodejs && copyfiles -f 'scripts/*' build/workspace && copyfiles -f 'build/src/*' build/workspace && cd build/workspace && bestzip ../layer.zip *"
23+
"prepare": "npm run compile && npm run install-externals && npm run package",
24+
"compile": "webpack",
25+
"package": "cd build/workspace && bestzip ../layer.zip *",
26+
"postcompile": "copyfiles -f 'scripts/*' build/workspace && copyfiles -f 'build/src/*' build/workspace"
2527
},
2628
"keywords": [
2729
"awsdistroopentelemetry",
@@ -34,5 +36,10 @@
3436
],
3537
"dependencies": {
3638
"@aws/aws-distro-opentelemetry-node-autoinstrumentation": "file:../../../aws-distro-opentelemetry-node-autoinstrumentation/aws-aws-distro-opentelemetry-node-autoinstrumentation-0.5.0-dev0.tgz"
39+
},
40+
"devDependencies": {
41+
"ts-loader": "^9.5.2",
42+
"webpack": "^5.98.0",
43+
"webpack-cli": "^6.0.1"
3744
}
3845
}

lambda-layer/packages/layer/scripts/otel-instrument

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ _is_esm_handler() {
2929
}
3030

3131
if _is_esm_handler || [[ ${HANDLER_IS_ESM} == true ]]; then
32-
export NODE_OPTIONS="${NODE_OPTIONS} --import @aws/aws-distro-opentelemetry-node-autoinstrumentation/register --experimental-loader=@opentelemetry/instrumentation/hook.mjs"
32+
export NODE_OPTIONS="${NODE_OPTIONS} --import /opt/wrapper.js --experimental-loader=import-in-the-middle/hook.mjs"
3333
export HANDLER_IS_ESM=true
3434
else
3535
export NODE_OPTIONS="${NODE_OPTIONS} --require /opt/wrapper.js"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "../../tsconfig.esm",
3+
"compilerOptions": {
4+
"rootDir": ".",
5+
"outDir": "build",
6+
},
7+
"include": [
8+
"src/**/*.ts",
9+
"test/**/*.ts"
10+
]
11+
}

aws-distro-opentelemetry-node-autoinstrumentation/webpack.config.js renamed to lambda-layer/packages/layer/webpack.config.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
const path = require('path');
22

33
module.exports = {
4-
entry: './src/register.ts',
4+
entry: './src/wrapper.ts',
55
target: 'node',
66
mode: 'production',
77
externalsPresets: { node: true },
8+
externals: [
9+
'import-in-the-middle',
10+
'@aws-sdk',
11+
],
812
output: {
913
path: path.resolve('./build/src'),
10-
filename: 'register.js',
14+
filename: 'wrapper.js',
1115
library: {
1216
type: 'commonjs2',
1317
}

lambda-layer/tsconfig.esm.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"compilerOptions": {
3+
"moduleResolution": "node",
4+
"module": "es2020",
5+
"target": "es2020",
6+
"allowUnreachableCode": false,
7+
"allowUnusedLabels": false,
8+
"declaration": true,
9+
"declarationMap": true,
10+
"esModuleInterop": true,
11+
"forceConsistentCasingInFileNames": true,
12+
"noEmitOnError": true,
13+
"noFallthroughCasesInSwitch": true,
14+
"noImplicitReturns": true,
15+
"noUnusedLocals": true,
16+
"pretty": true,
17+
"sourceMap": true,
18+
"strict": true,
19+
"strictNullChecks": true,
20+
"incremental": true,
21+
"newLine": "LF"
22+
},
23+
"exclude": [
24+
"node_modules"
25+
]
26+
}
27+

0 commit comments

Comments
 (0)