Skip to content

Commit b202640

Browse files
authored
avoid setting cold start on managed instances mode (#1008)
# What? Skips setting cold start on Managed Instances # Why? [SVLS-8232](https://datadoghq.atlassian.net/browse/SVLS-8232) [SVLS-8232]: https://datadoghq.atlassian.net/browse/SVLS-8232?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
1 parent 9f93370 commit b202640

2 files changed

Lines changed: 29 additions & 7 deletions

File tree

bottlecap/src/lifecycle/invocation/processor.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,13 @@ impl Processor {
255255
self.runtime = Some(runtime);
256256
}
257257

258-
self.dynamic_tags
259-
.insert(String::from("cold_start"), cold_start.to_string());
258+
// Skip cold_start tag in Managed Instance mode
259+
// We don't want to send this tag for spans, as the experience
260+
// won't look good due to the time gap in the flame graph.
261+
if !self.aws_config.is_managed_instance_mode() {
262+
self.dynamic_tags
263+
.insert(String::from("cold_start"), cold_start.to_string());
264+
}
260265

261266
if proactive_initialization {
262267
self.dynamic_tags.insert(
@@ -306,6 +311,14 @@ impl Processor {
306311
return;
307312
};
308313

314+
// Skip creating cold start span in Managed Instances
315+
// Although the telemetry is correct, we instead decide
316+
// to not send it since the flame graph would show a big
317+
// gap between the init and the first invocation.
318+
if self.aws_config.is_managed_instance_mode() {
319+
return;
320+
}
321+
309322
// Create a cold start span
310323
let mut cold_start_span = create_empty_span(
311324
String::from("aws.lambda.cold_start"),

integration-tests/tests/lmi.test.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,31 @@ describe('LMI Integration Tests', () => {
6767
expect(awsLambdaSpan?.attributes.custom.init_type).toBe('lambda-managed-instances')
6868
})
6969
// SVLS-8232
70-
it('aws.lambda.span should have cold_start set to false if no cold_start operation', () => {
70+
// In Managed Instance mode, cold_start span and tag are not sent by bottlecap
71+
// because the concept is less meaningful with concurrent invocations
72+
// and it would create a poor flame graph experience due to time gaps.
73+
//
74+
// Note: Node and Python tracers (dd-trace-js, dd-trace-py) set their own cold_start
75+
// attribute on spans independently, so we skip the tag check for those runtimes.
76+
it('aws.lambda.span should NOT have cold_start span or tag in LMI mode', () => {
7177
const trace = results[runtime].traces![0];
7278

73-
// The presence of 'aws.lambda.cold_start' span indicates a cold start
79+
// Verify no 'aws.lambda.cold_start' span exists in LMI mode
7480
const coldStartSpan = trace.spans.find((span: any) =>
7581
span.attributes.operation_name === 'aws.lambda.cold_start'
7682
);
83+
expect(coldStartSpan).toBeUndefined();
7784

7885
const awsLambdaSpan = trace.spans.find((span: any) =>
7986
span.attributes.operation_name === 'aws.lambda'
8087
);
8188
expect(awsLambdaSpan).toBeDefined(); // Ensure span exists before checking attributes
8289

83-
// Only check cold_start attribute when no dedicated cold_start span exists
84-
if (!coldStartSpan) {
85-
expect(awsLambdaSpan?.attributes.custom.cold_start).toBe('false');
90+
// Skip cold_start tag check for Node and Python since their tracer libraries
91+
// (dd-trace-js, dd-trace-py) set the cold_start attribute independently.
92+
// Only verify for Java and dotnet where bottlecap controls the span.
93+
if (runtime !== 'node' && runtime !== 'python') {
94+
expect(awsLambdaSpan?.attributes.custom.cold_start).toBeUndefined();
8695
}
8796
})
8897

0 commit comments

Comments
 (0)