Skip to content

Commit 32e8ffc

Browse files
authored
fix: omit creating cold start on LMI (#717)
* omit creating cold start on LMI * fmt
1 parent d7a4a40 commit 32e8ffc

5 files changed

Lines changed: 77 additions & 18 deletions

File tree

src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
setSandboxInit,
2222
setLogger,
2323
setLogLevel,
24+
isManagedInstancesMode,
2425
} from "./utils";
2526
import { getEnhancedMetricTags } from "./metrics/enhanced-metrics";
2627
import { DatadogTraceHeaders } from "./trace/context/extractor";
@@ -106,7 +107,9 @@ export const _metricsQueue: MetricsQueue = new MetricsQueue();
106107
let currentMetricsListener: MetricsListener | undefined;
107108
let currentTraceListener: TraceListener | undefined;
108109

109-
if (getEnvValue(coldStartTracingEnvVar, "true").toLowerCase() === "true") {
110+
// Skip cold start tracing subscription in managed instances mode
111+
// In managed instances, the tracer library handles cold start independently
112+
if (getEnvValue(coldStartTracingEnvVar, "true").toLowerCase() === "true" && !isManagedInstancesMode()) {
110113
subscribeToDC();
111114
}
112115

src/trace/listener.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { patchHttp, unpatchHttp } from "./patch-http";
55
import { extractTriggerTags, extractHTTPStatusCodeTag, parseEventSource } from "./trigger";
66
import { ColdStartTracerConfig, ColdStartTracer } from "./cold-start-tracer";
77
import { logDebug, tagObject } from "../utils";
8-
import { didFunctionColdStart, isProactiveInitialization } from "../utils/cold-start";
8+
import { didFunctionColdStart, isProactiveInitialization, isManagedInstancesMode } from "../utils/cold-start";
99
import { datadogLambdaVersion } from "../constants";
1010
import { ddtraceVersion, parentSpanFinishTimeHeader, DD_SERVICE_ENV_VAR } from "./constants";
1111
import { patchConsole } from "./patch-console";
@@ -179,20 +179,27 @@ export class TraceListener {
179179
}
180180
const coldStartNodes = getTraceTree();
181181
if (coldStartNodes.length > 0) {
182-
const coldStartConfig: ColdStartTracerConfig = {
183-
tracerWrapper: this.tracerWrapper,
184-
parentSpan:
185-
didFunctionColdStart() || isProactiveInitialization()
186-
? this.inferredSpan || this.wrappedCurrentSpan
187-
: this.wrappedCurrentSpan,
188-
lambdaFunctionName: this.context?.functionName,
189-
currentSpanStartTime: this.wrappedCurrentSpan?.startTime(),
190-
minDuration: this.config.minColdStartTraceDuration,
191-
ignoreLibs: this.config.coldStartTraceSkipLib,
192-
isColdStart: didFunctionColdStart() || isProactiveInitialization(),
193-
};
194-
const coldStartTracer = new ColdStartTracer(coldStartConfig);
195-
coldStartTracer.trace(coldStartNodes);
182+
// Skip creating cold start spans in managed instances mode
183+
// since the gap between the sandbox init and the function
184+
// invocation might be too large to provide a useful trace and
185+
// experience
186+
if (!isManagedInstancesMode()) {
187+
const coldStartConfig: ColdStartTracerConfig = {
188+
tracerWrapper: this.tracerWrapper,
189+
parentSpan:
190+
didFunctionColdStart() || isProactiveInitialization()
191+
? this.inferredSpan || this.wrappedCurrentSpan
192+
: this.wrappedCurrentSpan,
193+
lambdaFunctionName: this.context?.functionName,
194+
currentSpanStartTime: this.wrappedCurrentSpan?.startTime(),
195+
minDuration: this.config.minColdStartTraceDuration,
196+
ignoreLibs: this.config.coldStartTraceSkipLib,
197+
isColdStart: didFunctionColdStart() || isProactiveInitialization(),
198+
};
199+
const coldStartTracer = new ColdStartTracer(coldStartConfig);
200+
coldStartTracer.trace(coldStartNodes);
201+
}
202+
// Always clear the tree to prevent memory leaks, even if we skip span creation
196203
clearTraceTree();
197204
}
198205
if (this.triggerTags) {

src/utils/cold-start.spec.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { _resetColdStart, didFunctionColdStart, setSandboxInit, isProactiveInitialization } from "./cold-start";
1+
import {
2+
_resetColdStart,
3+
didFunctionColdStart,
4+
setSandboxInit,
5+
isProactiveInitialization,
6+
isManagedInstancesMode,
7+
} from "./cold-start";
28

39
beforeEach(_resetColdStart);
410
afterAll(_resetColdStart);
@@ -45,4 +51,31 @@ describe("cold-start", () => {
4551
expect(didFunctionColdStart()).toEqual(false);
4652
expect(isProactiveInitialization()).toEqual(false);
4753
});
54+
55+
it("identifies managed instances mode when AWS_LAMBDA_INITIALIZATION_TYPE is set", () => {
56+
const originalValue = process.env.AWS_LAMBDA_INITIALIZATION_TYPE;
57+
58+
process.env.AWS_LAMBDA_INITIALIZATION_TYPE = "lambda-managed-instances";
59+
expect(isManagedInstancesMode()).toEqual(true);
60+
61+
process.env.AWS_LAMBDA_INITIALIZATION_TYPE = originalValue;
62+
});
63+
64+
it("identifies non-managed instances mode when AWS_LAMBDA_INITIALIZATION_TYPE is not set", () => {
65+
const originalValue = process.env.AWS_LAMBDA_INITIALIZATION_TYPE;
66+
67+
delete process.env.AWS_LAMBDA_INITIALIZATION_TYPE;
68+
expect(isManagedInstancesMode()).toEqual(false);
69+
70+
process.env.AWS_LAMBDA_INITIALIZATION_TYPE = originalValue;
71+
});
72+
73+
it("identifies non-managed instances mode when AWS_LAMBDA_INITIALIZATION_TYPE has different value", () => {
74+
const originalValue = process.env.AWS_LAMBDA_INITIALIZATION_TYPE;
75+
76+
process.env.AWS_LAMBDA_INITIALIZATION_TYPE = "on-demand";
77+
expect(isManagedInstancesMode()).toEqual(false);
78+
79+
process.env.AWS_LAMBDA_INITIALIZATION_TYPE = originalValue;
80+
});
4881
});

src/utils/cold-start.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ export function getSandboxInitTags(): string[] {
3737
return tags;
3838
}
3939

40+
/**
41+
* Checks if the Lambda function is running in managed instances mode.
42+
* In managed instances mode, we should not create cold start tracing spans
43+
* as the tracer library handles this independently.
44+
* @returns true if running in managed instances mode, false otherwise
45+
*/
46+
export function isManagedInstancesMode(): boolean {
47+
return process.env.AWS_LAMBDA_INITIALIZATION_TYPE === "lambda-managed-instances";
48+
}
49+
4050
// For testing, reset the globals to their original values
4151
export function _resetColdStart() {
4252
functionDidColdStart = true;

src/utils/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
export { didFunctionColdStart, getSandboxInitTags, setSandboxInit, isProactiveInitialization } from "./cold-start";
1+
export {
2+
didFunctionColdStart,
3+
getSandboxInitTags,
4+
setSandboxInit,
5+
isProactiveInitialization,
6+
isManagedInstancesMode,
7+
} from "./cold-start";
28
export { promisifiedHandler } from "./handler";
39
export { Timer } from "./timer";
410
export { logWarning, logError, logDebug, Logger, setLogLevel, setLogger, LogLevel } from "./log";

0 commit comments

Comments
 (0)