diff --git a/src/index.ts b/src/index.ts index 91119fe6..deb8245e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,6 +21,7 @@ import { setSandboxInit, setLogger, setLogLevel, + isManagedInstancesMode, } from "./utils"; import { getEnhancedMetricTags } from "./metrics/enhanced-metrics"; import { DatadogTraceHeaders } from "./trace/context/extractor"; @@ -106,7 +107,9 @@ export const _metricsQueue: MetricsQueue = new MetricsQueue(); let currentMetricsListener: MetricsListener | undefined; let currentTraceListener: TraceListener | undefined; -if (getEnvValue(coldStartTracingEnvVar, "true").toLowerCase() === "true") { +// Skip cold start tracing subscription in managed instances mode +// In managed instances, the tracer library handles cold start independently +if (getEnvValue(coldStartTracingEnvVar, "true").toLowerCase() === "true" && !isManagedInstancesMode()) { subscribeToDC(); } diff --git a/src/trace/listener.ts b/src/trace/listener.ts index 1e312a71..49c46af7 100644 --- a/src/trace/listener.ts +++ b/src/trace/listener.ts @@ -5,7 +5,7 @@ import { patchHttp, unpatchHttp } from "./patch-http"; import { extractTriggerTags, extractHTTPStatusCodeTag, parseEventSource } from "./trigger"; import { ColdStartTracerConfig, ColdStartTracer } from "./cold-start-tracer"; import { logDebug, tagObject } from "../utils"; -import { didFunctionColdStart, isProactiveInitialization } from "../utils/cold-start"; +import { didFunctionColdStart, isProactiveInitialization, isManagedInstancesMode } from "../utils/cold-start"; import { datadogLambdaVersion } from "../constants"; import { ddtraceVersion, parentSpanFinishTimeHeader, DD_SERVICE_ENV_VAR } from "./constants"; import { patchConsole } from "./patch-console"; @@ -179,20 +179,27 @@ export class TraceListener { } const coldStartNodes = getTraceTree(); if (coldStartNodes.length > 0) { - const coldStartConfig: ColdStartTracerConfig = { - tracerWrapper: this.tracerWrapper, - parentSpan: - didFunctionColdStart() || isProactiveInitialization() - ? this.inferredSpan || this.wrappedCurrentSpan - : this.wrappedCurrentSpan, - lambdaFunctionName: this.context?.functionName, - currentSpanStartTime: this.wrappedCurrentSpan?.startTime(), - minDuration: this.config.minColdStartTraceDuration, - ignoreLibs: this.config.coldStartTraceSkipLib, - isColdStart: didFunctionColdStart() || isProactiveInitialization(), - }; - const coldStartTracer = new ColdStartTracer(coldStartConfig); - coldStartTracer.trace(coldStartNodes); + // Skip creating cold start spans in managed instances mode + // since the gap between the sandbox init and the function + // invocation might be too large to provide a useful trace and + // experience + if (!isManagedInstancesMode()) { + const coldStartConfig: ColdStartTracerConfig = { + tracerWrapper: this.tracerWrapper, + parentSpan: + didFunctionColdStart() || isProactiveInitialization() + ? this.inferredSpan || this.wrappedCurrentSpan + : this.wrappedCurrentSpan, + lambdaFunctionName: this.context?.functionName, + currentSpanStartTime: this.wrappedCurrentSpan?.startTime(), + minDuration: this.config.minColdStartTraceDuration, + ignoreLibs: this.config.coldStartTraceSkipLib, + isColdStart: didFunctionColdStart() || isProactiveInitialization(), + }; + const coldStartTracer = new ColdStartTracer(coldStartConfig); + coldStartTracer.trace(coldStartNodes); + } + // Always clear the tree to prevent memory leaks, even if we skip span creation clearTraceTree(); } if (this.triggerTags) { diff --git a/src/utils/cold-start.spec.ts b/src/utils/cold-start.spec.ts index d66b6781..479659ad 100644 --- a/src/utils/cold-start.spec.ts +++ b/src/utils/cold-start.spec.ts @@ -1,4 +1,10 @@ -import { _resetColdStart, didFunctionColdStart, setSandboxInit, isProactiveInitialization } from "./cold-start"; +import { + _resetColdStart, + didFunctionColdStart, + setSandboxInit, + isProactiveInitialization, + isManagedInstancesMode, +} from "./cold-start"; beforeEach(_resetColdStart); afterAll(_resetColdStart); @@ -45,4 +51,31 @@ describe("cold-start", () => { expect(didFunctionColdStart()).toEqual(false); expect(isProactiveInitialization()).toEqual(false); }); + + it("identifies managed instances mode when AWS_LAMBDA_INITIALIZATION_TYPE is set", () => { + const originalValue = process.env.AWS_LAMBDA_INITIALIZATION_TYPE; + + process.env.AWS_LAMBDA_INITIALIZATION_TYPE = "lambda-managed-instances"; + expect(isManagedInstancesMode()).toEqual(true); + + process.env.AWS_LAMBDA_INITIALIZATION_TYPE = originalValue; + }); + + it("identifies non-managed instances mode when AWS_LAMBDA_INITIALIZATION_TYPE is not set", () => { + const originalValue = process.env.AWS_LAMBDA_INITIALIZATION_TYPE; + + delete process.env.AWS_LAMBDA_INITIALIZATION_TYPE; + expect(isManagedInstancesMode()).toEqual(false); + + process.env.AWS_LAMBDA_INITIALIZATION_TYPE = originalValue; + }); + + it("identifies non-managed instances mode when AWS_LAMBDA_INITIALIZATION_TYPE has different value", () => { + const originalValue = process.env.AWS_LAMBDA_INITIALIZATION_TYPE; + + process.env.AWS_LAMBDA_INITIALIZATION_TYPE = "on-demand"; + expect(isManagedInstancesMode()).toEqual(false); + + process.env.AWS_LAMBDA_INITIALIZATION_TYPE = originalValue; + }); }); diff --git a/src/utils/cold-start.ts b/src/utils/cold-start.ts index 26162e44..720d6eba 100644 --- a/src/utils/cold-start.ts +++ b/src/utils/cold-start.ts @@ -37,6 +37,16 @@ export function getSandboxInitTags(): string[] { return tags; } +/** + * Checks if the Lambda function is running in managed instances mode. + * In managed instances mode, we should not create cold start tracing spans + * as the tracer library handles this independently. + * @returns true if running in managed instances mode, false otherwise + */ +export function isManagedInstancesMode(): boolean { + return process.env.AWS_LAMBDA_INITIALIZATION_TYPE === "lambda-managed-instances"; +} + // For testing, reset the globals to their original values export function _resetColdStart() { functionDidColdStart = true; diff --git a/src/utils/index.ts b/src/utils/index.ts index 9ec6713a..45bc2bd8 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,10 @@ -export { didFunctionColdStart, getSandboxInitTags, setSandboxInit, isProactiveInitialization } from "./cold-start"; +export { + didFunctionColdStart, + getSandboxInitTags, + setSandboxInit, + isProactiveInitialization, + isManagedInstancesMode, +} from "./cold-start"; export { promisifiedHandler } from "./handler"; export { Timer } from "./timer"; export { logWarning, logError, logDebug, Logger, setLogLevel, setLogger, LogLevel } from "./log";