From 2622e4d87360f0fd9b3ddf94db82b5bc0dbb3986 Mon Sep 17 00:00:00 2001 From: Lucas Pimentel Date: Tue, 6 Oct 2026 13:54:30 -0400 Subject: [PATCH 1/3] perf(runtime): register dd-trace ESM loader hooks in-thread to reduce Lambda cold start time On Lambda's Node runtime, the tracer's ESM instrumentation hooks were installed through a background loader thread, because the runtime launches Node with require(esm) disabled. Each module load then paid synchronous round-trips to that thread, adding roughly 60 ms to cold-start init in local measurements with the AWS Runtime Interface Emulator. The hooks are now installed in-thread on Node versions that support it (22.22.3+, 24.11.1+, 25.1+, 26+). If in-thread installation fails partway, the background loader is not also installed, since a second registration would run the ESM instrumentation twice on every module. Older Node versions keep the previous behavior. --- src/handler.mjs | 2 +- src/handler.spec.ts | 38 +++- .../fixtures/loader-registration-spy.cjs | 27 +++ .../fixtures/published-handler-runner.mjs | 1 + src/runtime/module-importer.spec.ts | 178 +++++++++++++++--- src/runtime/module_importer.js | 102 +++++++++- 6 files changed, 319 insertions(+), 29 deletions(-) create mode 100644 src/runtime/fixtures/loader-registration-spy.cjs diff --git a/src/handler.mjs b/src/handler.mjs index 0150cd62..7c1a4208 100644 --- a/src/handler.mjs +++ b/src/handler.mjs @@ -21,7 +21,7 @@ if (process.env.DD_TRACE_STARTUP_LOGS === undefined) { } if (getEnvValue("DD_TRACE_ENABLED", "true").toLowerCase() === "true") { - initTracer(); + await initTracer(); } const taskRootEnv = getEnvValue(lambdaTaskRootEnvVar, ""); diff --git a/src/handler.spec.ts b/src/handler.spec.ts index af3d2cc8..58ab68e8 100644 --- a/src/handler.spec.ts +++ b/src/handler.spec.ts @@ -9,6 +9,7 @@ import * as zlib from "node:zlib"; const fixtureDirectory = path.join(__dirname, "runtime", "fixtures"); const handlerEntry = pathToFileURL(path.join(__dirname, "..", "dist", "handler.mjs")).href; const runnerPath = path.join(fixtureDirectory, "published-handler-runner.mjs"); +const loaderRegistrationSpyPath = path.join(fixtureDirectory, "loader-registration-spy.cjs"); const tracePayloads: Buffer[] = []; let agent: http.Server; @@ -104,10 +105,25 @@ async function runPublishedHandler(traceEnabled: boolean): Promise { delete env.OTEL_METRICS_EXPORTER; delete env.OTEL_TRACES_EXPORTER; - const child = spawn(process.execPath, [runnerPath], { - env, - stdio: ["ignore", "pipe", "pipe", "ipc"], - }); + const child = spawn( + process.execPath, + [ + // Test-only preload that records whether Module.register or + // Module.registerHooks was used for ESM loader registration. + "--require", + loaderRegistrationSpyPath, + // Mirrors the Lambda Node bootstrap, which disables require(esm) unless + // NODE_OPTIONS contains --experimental-require-module. + ...(process.allowedNodeEnvironmentFlags.has("--experimental-require-module") + ? ["--no-experimental-require-module"] + : []), + runnerPath, + ], + { + env, + stdio: ["ignore", "pipe", "pipe", "ipc"], + }, + ); const closePromise = once(child, "close") as Promise<[number | null, NodeJS.Signals | null]>; const messagePromise = once(child, "message") as Promise<[unknown]>; let standardOutput = ""; @@ -162,10 +178,20 @@ async function runPublishedHandler(traceEnabled: boolean): Promise { } const moduleWithRegister = Module as typeof Module & { register?: unknown }; +const moduleWithRegisterHooks = Module as typeof Module & { registerHooks?: unknown }; const nodeMajor = Number(process.versions.node.split(".")[0]); const supportsDurableFixture = nodeMajor >= 22 && typeof moduleWithRegister.register === "function"; const describeWithESMLoader = supportsDurableFixture ? describe : describe.skip; +// tslint:disable-next-line:no-var-requires +const { isSyncLoaderHookVersionSupported } = require("./runtime/module_importer") as { + isSyncLoaderHookVersionSupported(nodeVersion: string): boolean; +}; + +const syncHooksExpected = + isSyncLoaderHookVersionSupported(process.versions.node) && + typeof moduleWithRegisterHooks.registerHooks === "function"; + describeWithESMLoader("published ESM handler", () => { jest.setTimeout(30_000); @@ -192,7 +218,8 @@ describeWithESMLoader("published ESM handler", () => { const payload = Buffer.concat(tracePayloads); expect(message).toEqual({ - registerLoaded: true, + registerLoaded: !syncHooksExpected, + registrations: [syncHooksExpected ? "registerHooks" : "register"], result: expect.objectContaining({ Status: "SUCCEEDED" }), }); expect(payload.includes(Buffer.from("aws.lambda"))).toBe(true); @@ -204,6 +231,7 @@ describeWithESMLoader("published ESM handler", () => { expect(message).toEqual({ registerLoaded: false, + registrations: [], result: expect.objectContaining({ Status: "SUCCEEDED" }), }); expect(tracePayloads).toHaveLength(0); diff --git a/src/runtime/fixtures/loader-registration-spy.cjs b/src/runtime/fixtures/loader-registration-spy.cjs new file mode 100644 index 00000000..15afa25a --- /dev/null +++ b/src/runtime/fixtures/loader-registration-spy.cjs @@ -0,0 +1,27 @@ +"use strict"; + +// Preload that mirrors how the tests observe loader registration. It wraps +// Module.register and Module.registerHooks so the runner can report which +// registration API dd-trace used. The file name intentionally contains no +// "dd-trace" reference so esmLoaderAlreadyRegistered does not match it. +const Module = require("node:module"); + +globalThis.__ddLoaderRegistrations = []; + +const register = Module.register; +if (typeof register === "function") { + Module.register = function (...args) { + globalThis.__ddLoaderRegistrations.push("register"); + return register.apply(this, args); + }; +} + +const registerHooks = Module.registerHooks; +if (typeof registerHooks === "function") { + Module.registerHooks = function (...args) { + globalThis.__ddLoaderRegistrations.push("registerHooks"); + return registerHooks.apply(this, args); + }; +} + +Module.syncBuiltinESMExports(); diff --git a/src/runtime/fixtures/published-handler-runner.mjs b/src/runtime/fixtures/published-handler-runner.mjs index fa21d331..f205a3ad 100644 --- a/src/runtime/fixtures/published-handler-runner.mjs +++ b/src/runtime/fixtures/published-handler-runner.mjs @@ -37,6 +37,7 @@ const result = await handler( const exitSignal = once(process, "message"); process.send({ registerLoaded: require.cache[registerPath] !== undefined, + registrations: globalThis.__ddLoaderRegistrations ?? [], result, }); await exitSignal; diff --git a/src/runtime/module-importer.spec.ts b/src/runtime/module-importer.spec.ts index 3c572a11..1037af51 100644 --- a/src/runtime/module-importer.spec.ts +++ b/src/runtime/module-importer.spec.ts @@ -12,12 +12,27 @@ describe("module importer", () => { let init: jest.Mock; let logDebug: jest.Mock; let moduleRegister: jest.Mock; + let moduleRegisterHooks: jest.Mock; let registerLoader: jest.Mock; let tracer: Tracer; let updateDDTags: jest.Mock]>; const originalExecArgv = [...process.execArgv]; const originalNodeOptions = process.env.NODE_OPTIONS; + /** + * Requires the module under test and installs the default spies that keep + * the tests on the asynchronous loader fallback path. + */ + function requireModuleImporter() { + // tslint:disable-next-line:no-var-requires + const moduleImporter = require("./module_importer"); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(false); + jest + .spyOn(moduleImporter, "import") + .mockRejectedValue(new Error("loader-hook.mjs import should not have been called")); + return moduleImporter; + } + beforeEach(() => { jest.resetModules(); process.execArgv.splice(0, process.execArgv.length); @@ -25,6 +40,7 @@ describe("module importer", () => { logDebug = jest.fn(); moduleRegister = jest.fn(); + moduleRegisterHooks = jest.fn().mockReturnValue(true); registerLoader = jest.fn(); tracer = { use: jest.fn() }; init = jest.fn().mockReturnValue(tracer); @@ -39,6 +55,7 @@ describe("module importer", () => { jest.doMock("node:module", () => ({ ...jest.requireActual("node:module"), register: moduleRegister, + registerHooks: moduleRegisterHooks, })); }); @@ -51,75 +68,194 @@ describe("module importer", () => { } }); - it("initializes the tracer and loads its ESM registration entry point", () => { - const { initTracer } = require("./module_importer"); + it("initializes the tracer and loads its ESM registration entry point", async () => { + const { initTracer } = requireModuleImporter(); - expect(initTracer()).toBe(tracer); + await expect(initTracer()).resolves.toBe(tracer); expect(updateDDTags).toHaveBeenCalledWith({ "_dd.origin": "lambda" }); expect(init).toHaveBeenCalledWith({ tags: "_dd.origin:lambda" }); expect(tracer.use).toHaveBeenCalledWith("http", { blocklist: expect.any(RegExp) }); expect(registerLoader).toHaveBeenCalledTimes(1); }); - it("does not register again when NODE_OPTIONS preloads dd-trace", () => { + it("does not register again when NODE_OPTIONS preloads dd-trace", async () => { process.env.NODE_OPTIONS = "--import dd-trace/initialize.mjs"; - const { initTracer } = require("./module_importer"); + const moduleImporter = requireModuleImporter(); - expect(initTracer()).toBe(tracer); + await expect(moduleImporter.initTracer()).resolves.toBe(tracer); expect(registerLoader).not.toHaveBeenCalled(); + expect(moduleImporter.import).not.toHaveBeenCalled(); }); - it("does not register again when execArgv preloads dd-trace", () => { + it("does not register again when execArgv preloads dd-trace", async () => { process.execArgv.push("--require", "dd-trace/register.js"); - const { initTracer } = require("./module_importer"); + const moduleImporter = requireModuleImporter(); - expect(initTracer()).toBe(tracer); + await expect(moduleImporter.initTracer()).resolves.toBe(tracer); expect(registerLoader).not.toHaveBeenCalled(); + expect(moduleImporter.import).not.toHaveBeenCalled(); }); - it("registers when the Node arguments do not preload dd-trace", () => { + it("registers when the Node arguments do not preload dd-trace", async () => { process.env.NODE_OPTIONS = "--enable-source-maps"; process.execArgv.push("--trace-warnings"); - const { initTracer } = require("./module_importer"); + const { initTracer } = requireModuleImporter(); - expect(initTracer()).toBe(tracer); + await expect(initTracer()).resolves.toBe(tracer); expect(registerLoader).toHaveBeenCalledTimes(1); }); - it("falls back to the legacy loader when dd-trace has no registration entry point", () => { + it("falls back to the legacy loader when dd-trace has no registration entry point", async () => { + const { initTracer } = requireModuleImporter(); const error = Object.assign(new Error(`Cannot find module '${ddTraceRegisterPath}'`), { code: "MODULE_NOT_FOUND" }); jest.doMock(ddTraceRegisterPath, () => { throw error; }); - const { initTracer } = require("./module_importer"); - expect(initTracer()).toBe(tracer); + await expect(initTracer()).resolves.toBe(tracer); expect(moduleRegister).toHaveBeenCalledWith( pathToFileURL(path.join(path.dirname(ddTracePath), "loader-hook.mjs")), ); expect(logDebug).toHaveBeenCalledWith("registered dd-trace ESM loader hooks for ESM instrumentation"); }); - it("does not load the registration entry point without module.register", () => { + it("does not load the registration entry point without module.register", async () => { jest.doMock("node:module", () => ({ ...jest.requireActual("node:module"), register: undefined, + registerHooks: moduleRegisterHooks, })); - const { initTracer } = require("./module_importer"); + const { initTracer } = requireModuleImporter(); - expect(initTracer()).toBe(tracer); + await expect(initTracer()).resolves.toBe(tracer); expect(registerLoader).not.toHaveBeenCalled(); }); - it("keeps the initialized tracer when loader registration fails", () => { + it("keeps the initialized tracer when loader registration fails", async () => { + const { initTracer } = requireModuleImporter(); const error = new Error("registration failed"); jest.doMock(ddTraceRegisterPath, () => { throw error; }); - const { initTracer } = require("./module_importer"); - expect(initTracer()).toBe(tracer); + await expect(initTracer()).resolves.toBe(tracer); expect(moduleRegister).not.toHaveBeenCalled(); expect(logDebug).toHaveBeenCalledWith("failed to register dd-trace ESM loader hooks", { error }); }); + + it("registers the synchronous loader hooks when they are supported", async () => { + const registerSyncLoaderHooks = jest.fn().mockReturnValue(true); + const moduleImporter = requireModuleImporter(); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(true); + jest.spyOn(moduleImporter, "import").mockResolvedValue({ registerSyncLoaderHooks }); + const { initTracer } = moduleImporter; + + await expect(initTracer()).resolves.toBe(tracer); + expect(moduleImporter.import).toHaveBeenCalledWith( + pathToFileURL(path.join(path.dirname(ddTracePath), "loader-hook.mjs")).href, + ); + expect(registerSyncLoaderHooks).toHaveBeenCalledTimes(1); + expect(moduleRegisterHooks).not.toHaveBeenCalled(); + expect(registerLoader).not.toHaveBeenCalled(); + expect(moduleRegister).not.toHaveBeenCalled(); + expect(logDebug).toHaveBeenCalledWith("registered dd-trace synchronous ESM loader hooks"); + }); + + it("falls back to the asynchronous loader when the synchronous registration reports failure", async () => { + const moduleImporter = requireModuleImporter(); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(true); + jest.spyOn(moduleImporter, "import").mockResolvedValue({ registerSyncLoaderHooks: jest.fn().mockReturnValue(false) }); + const { initTracer } = moduleImporter; + + await expect(initTracer()).resolves.toBe(tracer); + expect(registerLoader).toHaveBeenCalledTimes(1); + expect(moduleRegister).not.toHaveBeenCalled(); + }); + + it("falls back to the asynchronous loader when loader-hook.mjs has no sync registration export", async () => { + const moduleImporter = requireModuleImporter(); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(true); + jest.spyOn(moduleImporter, "import").mockResolvedValue({}); + const { initTracer } = moduleImporter; + + await expect(initTracer()).resolves.toBe(tracer); + expect(registerLoader).toHaveBeenCalledTimes(1); + }); + + it("logs and falls back to the asynchronous loader when the loader-hook import fails", async () => { + const moduleImporter = requireModuleImporter(); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(true); + const error = new Error("import failed"); + jest.spyOn(moduleImporter, "import").mockRejectedValue(error); + const { initTracer } = moduleImporter; + + await expect(initTracer()).resolves.toBe(tracer); + expect(logDebug).toHaveBeenCalledWith("failed to register dd-trace synchronous ESM loader hooks, falling back", { + error, + }); + expect(registerLoader).toHaveBeenCalledTimes(1); + }); + + it("does not fall back when the synchronous registration throws after loading", async () => { + const moduleImporter = requireModuleImporter(); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(true); + const error = new Error("registration threw"); + jest + .spyOn(moduleImporter, "import") + .mockResolvedValue({ registerSyncLoaderHooks: jest.fn().mockImplementation(() => { throw error; }) }); + const { initTracer } = moduleImporter; + + await expect(initTracer()).resolves.toBe(tracer); + expect(logDebug).toHaveBeenCalledWith( + "dd-trace synchronous ESM loader hook registration threw; skipping the asynchronous loader to avoid registering hooks twice", + { error }, + ); + expect(registerLoader).not.toHaveBeenCalled(); + expect(moduleRegister).not.toHaveBeenCalled(); + }); + + it("does not import loader-hook.mjs when the Node version is unsupported", async () => { + const moduleImporter = requireModuleImporter(); + const { initTracer } = moduleImporter; + + await expect(initTracer()).resolves.toBe(tracer); + expect(moduleImporter.import).not.toHaveBeenCalled(); + expect(registerLoader).toHaveBeenCalledTimes(1); + }); + + it("does not import loader-hook.mjs without module.registerHooks", async () => { + jest.doMock("node:module", () => ({ + ...jest.requireActual("node:module"), + register: moduleRegister, + registerHooks: undefined, + })); + const moduleImporter = requireModuleImporter(); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(true); + const { initTracer } = moduleImporter; + + await expect(initTracer()).resolves.toBe(tracer); + expect(moduleImporter.import).not.toHaveBeenCalled(); + expect(registerLoader).toHaveBeenCalledTimes(1); + }); + + it.each([ + ["18.20.0", false], + ["20.19.0", false], + ["22.11.0", false], + ["22.22.2", false], + ["23.11.0", false], + ["24.11.0", false], + ["25.0.0", false], + ["22.22.3", true], + ["22.23.0", true], + ["24.11.1", true], + ["24.12.0", true], + ["25.1.0", true], + ["26.0.0", true], + ["27.0.0", true], + ])("reports synchronous loader hook support for Node %s as %s", (nodeVersion, expected) => { + const { isSyncLoaderHookVersionSupported } = require("./module_importer"); + + expect(isSyncLoaderHookVersionSupported(nodeVersion)).toBe(expected); + }); }); diff --git a/src/runtime/module_importer.js b/src/runtime/module_importer.js index 401678e3..a51022d5 100644 --- a/src/runtime/module_importer.js +++ b/src/runtime/module_importer.js @@ -21,6 +21,102 @@ function esmLoaderAlreadyRegistered() { return false; } +// Mirrors isSyncLoaderHookVersionSupported from dd-trace's register.js. The +// nodejs/node#59929 fix that sync loader hooks rely on shipped in Node +// 22.22.3, 24.11.1, 25.1.0, and 26.0.0. +/** + * @param {string} nodeVersion + * @returns {boolean} + */ +function isSyncLoaderHookVersionSupported(nodeVersion) { + const [major, minor, patch] = nodeVersion.split(".").map(Number); + if (major >= 26) { + return true; + } + if (major === 25) { + return minor >= 1; + } + if (major === 24) { + return minor > 11 || (minor === 11 && patch >= 1); + } + if (major === 22) { + return minor > 22 || (minor === 22 && patch >= 3); + } + return false; +} + +/** + * Registration result for the synchronous, in-thread ESM loader hooks: + * - "registered": hooks were installed in-thread. + * - "unavailable": the sync path was not usable and nothing was installed; + * the caller may fall back to the asynchronous loader. + * - "failed-after-load": loader-hook.mjs loaded but registerSyncLoaderHooks + * threw. The hooks may already be installed, so the caller must NOT fall + * back: we cannot tell whether registration ran, and double registration + * would run the rewriter on every module twice. Missing ESM instrumentation + * in this rare case matches the behavior before explicit registration was + * added. + * + * @typedef {"registered" | "unavailable" | "failed-after-load"} SyncRegistrationResult + */ + +/** + * Registers dd-trace's synchronous, in-thread ESM loader hooks. dd-trace's + * register.js reaches these hooks through require(esm), which the Lambda + * bootstrap disables with --no-experimental-require-module, while import() + * is not affected. + * + * @param {string} tracerPath + * @returns {Promise} + */ +async function registerSyncESMLoaderHooks(tracerPath) { + if (typeof Module.registerHooks !== "function" || !exports.isSyncLoaderHookVersionSupported(process.versions.node)) { + return "unavailable"; + } + + const loaderHookUrl = pathToFileURL(join(dirname(tracerPath), "loader-hook.mjs")).href; + const loaderHookModule = await exports.import(loaderHookUrl); + if (typeof loaderHookModule.registerSyncLoaderHooks !== "function") { + return "unavailable"; + } + try { + return loaderHookModule.registerSyncLoaderHooks() === true ? "registered" : "unavailable"; + } catch (error) { + logDebug( + "dd-trace synchronous ESM loader hook registration threw; skipping the asynchronous loader to avoid registering hooks twice", + { error }, + ); + return "failed-after-load"; + } +} + +/** + * @param {string} tracerPath + */ +async function registerESMLoaderHooksPreferSync(tracerPath) { + if (typeof Module.register !== "function" || esmLoaderAlreadyRegistered()) { + return; + } + + let syncResult; + try { + syncResult = await registerSyncESMLoaderHooks(tracerPath); + } catch (error) { + // The dynamic import itself failed, so no hooks were installed. + logDebug("failed to register dd-trace synchronous ESM loader hooks, falling back", { error }); + registerESMLoaderHooks(tracerPath); + return; + } + if (syncResult === "registered") { + logDebug("registered dd-trace synchronous ESM loader hooks"); + return; + } + if (syncResult === "failed-after-load") { + return; + } + registerESMLoaderHooks(tracerPath); +} + /** * @param {string} tracerPath */ @@ -54,7 +150,9 @@ exports.import = function (path) { return import(path); } -exports.initTracer = function () { +exports.isSyncLoaderHookVersionSupported = isSyncLoaderHookVersionSupported; + +exports.initTracer = async function () { // Looks for the function local version of dd-trace first, before using // the version provided by the layer const searchPaths = ["/var/task/node_modules", ...module.paths]; @@ -70,6 +168,6 @@ exports.initTracer = function () { blocklist: /:8124\/lambda/, }); // The durable runtime ignores NODE_OPTIONS, so install hooks explicitly. - registerESMLoaderHooks(tracerPath); + await registerESMLoaderHooksPreferSync(tracerPath); return tracer; } From f1bf76b14e54b77710126bd6aaaa50fb66ac2a2a Mon Sep 17 00:00:00 2001 From: Lucas Pimentel Date: Tue, 6 Oct 2026 17:02:41 -0400 Subject: [PATCH 2/3] test: cover preloaded ESM hooks on supported Node --- src/runtime/module-importer.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/runtime/module-importer.spec.ts b/src/runtime/module-importer.spec.ts index 1037af51..a04a43fe 100644 --- a/src/runtime/module-importer.spec.ts +++ b/src/runtime/module-importer.spec.ts @@ -81,6 +81,7 @@ describe("module importer", () => { it("does not register again when NODE_OPTIONS preloads dd-trace", async () => { process.env.NODE_OPTIONS = "--import dd-trace/initialize.mjs"; const moduleImporter = requireModuleImporter(); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(true); await expect(moduleImporter.initTracer()).resolves.toBe(tracer); expect(registerLoader).not.toHaveBeenCalled(); @@ -90,6 +91,7 @@ describe("module importer", () => { it("does not register again when execArgv preloads dd-trace", async () => { process.execArgv.push("--require", "dd-trace/register.js"); const moduleImporter = requireModuleImporter(); + jest.spyOn(moduleImporter, "isSyncLoaderHookVersionSupported").mockReturnValue(true); await expect(moduleImporter.initTracer()).resolves.toBe(tracer); expect(registerLoader).not.toHaveBeenCalled(); From edc7a8c6f58d6ad4d4468db08e6ae0539d5f5e56 Mon Sep 17 00:00:00 2001 From: Lucas Pimentel Date: Tue, 6 Oct 2026 17:44:26 -0400 Subject: [PATCH 3/3] test: update node26 proactive-init log snapshot for trace-correlated warnings --- .../logs/cjs-proactive-init_node26.log | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/integration_tests_local/snapshots/logs/cjs-proactive-init_node26.log b/integration_tests_local/snapshots/logs/cjs-proactive-init_node26.log index f6cb162c..b57ed089 100644 --- a/integration_tests_local/snapshots/logs/cjs-proactive-init_node26.log +++ b/integration_tests_local/snapshots/logs/cjs-proactive-init_node26.log @@ -21,7 +21,7 @@ START RequestId: XXXX Version: $LATEST "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", "level": "ERROR", "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." } { "traces": [ @@ -133,7 +133,7 @@ START RequestId: XXXX Version: $LATEST "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", "level": "ERROR", "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." } { "traces": [ @@ -244,8 +244,10 @@ START RequestId: XXXX Version: $LATEST "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", "level": "ERROR", "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." } +END RequestId: XXXX +REPORT RequestId: XXXX Duration: XXXX ms { "traces": [ [ @@ -333,8 +335,6 @@ START RequestId: XXXX Version: $LATEST ] ] } -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms START RequestId: XXXX Version: $LATEST { "e": XXXX, @@ -355,7 +355,7 @@ START RequestId: XXXX Version: $LATEST "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", "level": "ERROR", "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." } { "traces": [ @@ -466,10 +466,8 @@ START RequestId: XXXX Version: $LATEST "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", "level": "ERROR", "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." } -END RequestId: XXXX -REPORT RequestId: XXXX Duration: XXXX ms { "traces": [ [ @@ -556,6 +554,8 @@ REPORT RequestId: XXXX Duration: XXXX ms ] ] } +END RequestId: XXXX +REPORT RequestId: XXXX Duration: XXXX ms START RequestId: XXXX Version: $LATEST { "e": XXXX, @@ -576,7 +576,7 @@ START RequestId: XXXX Version: $LATEST "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", "level": "ERROR", "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." } { "traces": [ @@ -686,7 +686,7 @@ START RequestId: XXXX Version: $LATEST "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", "level": "ERROR", "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." } { "traces": [ @@ -777,6 +777,12 @@ START RequestId: XXXX Version: $LATEST END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms START RequestId: XXXX Version: $LATEST +{ + "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", + "level": "ERROR", + "requestId": "XXXX", + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." +} { "e": XXXX, "m": "aws.lambda.enhanced.invocations", @@ -792,12 +798,6 @@ START RequestId: XXXX Version: $LATEST ], "v": 1 } -{ - "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", - "level": "ERROR", - "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." -} { "traces": [ [ @@ -905,7 +905,7 @@ START RequestId: XXXX Version: $LATEST "timestamp": "XXXX-XX-XXTXX:XX:XX.XXXZ", "level": "ERROR", "requestId": "XXXX", - "message": "(node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." + "message": "[dd.trace_id=XXXX dd.span_id=XXXX] (node:XX) TimeoutOverflowWarning: XXXX does not fit into a 32-bit signed integer.\nTimeout duration was set to 1." } { "traces": [