From a3033a4f5d24f5b100878ee881005778ad349c71 Mon Sep 17 00:00:00 2001 From: Arya Date: Tue, 24 Feb 2026 13:40:00 +0530 Subject: [PATCH] fix(aws-lambda): reducing cold start timing --- packages/aws-lambda-auto-wrap/esm/index.js | 76 +++++++++++++++------- packages/aws-lambda-auto-wrap/src/index.js | 55 ++++++++++++---- 2 files changed, 96 insertions(+), 35 deletions(-) diff --git a/packages/aws-lambda-auto-wrap/esm/index.js b/packages/aws-lambda-auto-wrap/esm/index.js index 9b41cf1c8d..1b9b7d7474 100644 --- a/packages/aws-lambda-auto-wrap/esm/index.js +++ b/packages/aws-lambda-auto-wrap/esm/index.js @@ -4,37 +4,67 @@ 'use strict'; -const instana = require('@instana/aws-lambda'); -const supportedVersion = require('@instana/core').tracing.supportedVersion; -const localUtils = require('./utils'); -// eslint-disable-next-line instana/no-unsafe-require -const semver = require('semver'); - -// NOTE: The esm handler can be used for Lambdas with commonjs or es module. -// See https://github.com/nodejs/node/pull/35249 -if (!supportedVersion(process.versions.node)) { - throw new localUtils.errors.lambda.ImportModuleError( - `Your Lambda function is using ${process.versions.node}. This version is not supported.` + - 'Please use a layer version which is compatible with your Node.js version.' + - 'See https://www.ibm.com/docs/en/instana-observability/current?topic=lambda-aws-native-tracing-nodejs' - ); -} +let instana; +let supportedVersion; +let localUtils; +let semver; +let wrappedHandler; +let initStartTime; // Node.js 24+ removed support for callback-based handlers (3 parameters). // For Node.js < 24, we preserve the callback signature for backward compatibility. -const latestRuntime = semver.gte(process.version, '24.0.0'); +function isLatestRuntime() { + if (!semver) { + // eslint-disable-next-line instana/no-unsafe-require + semver = require('semver'); + } + return semver.gte(process.version, '24.0.0'); +} + +async function initializeHandler() { + if (wrappedHandler) { + return wrappedHandler; + } + + initStartTime = Date.now(); + + instana = require('@instana/aws-lambda'); + supportedVersion = require('@instana/core').tracing.supportedVersion; + localUtils = require('./utils'); + + const loadTime = Date.now() - initStartTime; + // eslint-disable-next-line no-console + console.log(`[Instana ESM] Dependencies loaded in ${loadTime}ms`); + + // NOTE: The esm handler can be used for Lambdas with commonjs or es module. + // See https://github.com/nodejs/node/pull/35249 + if (!supportedVersion(process.versions.node)) { + throw new localUtils.errors.lambda.ImportModuleError( + `Your Lambda function is using ${process.versions.node}. This version is not supported.` + + 'Please use a layer version which is compatible with your Node.js version.' + + 'See https://www.ibm.com/docs/en/instana-observability/current?topic=lambda-aws-native-tracing-nodejs' + ); + } + + const targetHandler = await loadTargetHandlerFunction(); + wrappedHandler = instana.wrap(targetHandler); + + const totalTime = Date.now() - initStartTime; + // eslint-disable-next-line no-console + console.log(`[Instana ESM] Handler initialization completed in ${totalTime}ms`); + + return wrappedHandler; +} -if (latestRuntime) { +if (isLatestRuntime()) { exports.handler = async function instanaAutowrapHandler(event, context) { - const targetHandler = await loadTargetHandlerFunction(); - const wrappedHandler = instana.wrap(targetHandler); - return wrappedHandler(event, context); + const handler = await initializeHandler(); + return handler(event, context); }; } else { exports.handler = async function instanaAutowrapHandler(event, context, callback) { - const targetHandler = await loadTargetHandlerFunction(); - const wrappedHandler = instana.wrap(targetHandler); - return wrappedHandler(event, context, callback); + const handler = await initializeHandler(); + return handler(event, context, callback); }; } diff --git a/packages/aws-lambda-auto-wrap/src/index.js b/packages/aws-lambda-auto-wrap/src/index.js index 33848950dd..daea334718 100644 --- a/packages/aws-lambda-auto-wrap/src/index.js +++ b/packages/aws-lambda-auto-wrap/src/index.js @@ -5,29 +5,56 @@ 'use strict'; -const instana = require('@instana/aws-lambda'); -// eslint-disable-next-line instana/no-unsafe-require -const semver = require('semver'); -const localUtils = require('./utils'); - +let instana; +let semver; +let localUtils; let wrappedHandler; let capturedError; +let initStartTime; + +// Node.js 24+ removed support for callback-based handlers (3 parameters). +// For Node.js < 24, we preserve the callback signature for backward compatibility. +function isLatestRuntime() { + if (!semver) { + // eslint-disable-next-line instana/no-unsafe-require + semver = require('semver'); + } + return semver.gte(process.version, '24.0.0'); +} + +function initializeHandler() { + if (wrappedHandler || capturedError) { + return; + } -if (!wrappedHandler) { try { + initStartTime = Date.now(); + + instana = require('@instana/aws-lambda'); + localUtils = require('./utils'); + + const loadTime = Date.now() - initStartTime; + // eslint-disable-next-line no-console + console.log(`[Instana] Dependencies loaded in ${loadTime}ms`); + const targetHandler = loadTargetHandlerFunction(); wrappedHandler = instana.wrap(targetHandler); + + const totalTime = Date.now() - initStartTime; + // eslint-disable-next-line no-console + console.log(`[Instana] Handler initialization completed in ${totalTime}ms`); } catch (e) { capturedError = e; + // eslint-disable-next-line no-console + console.error('[Instana] Handler initialization failed:', e.message); } } -// Node.js 24+ removed support for callback-based handlers (3 parameters). -// For Node.js < 24, we preserve the callback signature for backward compatibility. -const latestRuntime = semver.gte(process.version, '24.0.0'); -if (latestRuntime) { +if (isLatestRuntime()) { exports.handler = async function instanaAutowrapHandler(event, context) { - if (!wrappedHandler) { + initializeHandler(); + + if (capturedError) { throw capturedError; } @@ -35,7 +62,11 @@ if (latestRuntime) { }; } else { exports.handler = function instanaAutowrapHandler(event, context, callback) { - if (!wrappedHandler) return callback(capturedError); + initializeHandler(); + + if (capturedError) { + return callback(capturedError); + } return wrappedHandler(event, context, callback); };