Skip to content

Commit 0af9e16

Browse files
authored
Merge branch 'main' into feat/support-eb-dsm-extraction
2 parents 98c9ac1 + 71b7244 commit 0af9e16

3 files changed

Lines changed: 48 additions & 2 deletions

File tree

‎datadog_lambda/cold_start.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,11 @@ def trace(self, root_nodes: List[ImportNode] = root_nodes):
202202
cold_start_span = self.create_cold_start_span(cold_start_span_start_time_ns)
203203
while root_nodes:
204204
root_node = root_nodes.pop()
205-
parent = root_node.context or cold_start_span
205+
# Modules lazily imported during the invocation hang off the function
206+
# span, not the span active at import time: nesting them under a
207+
# client span (e.g. a DynamoDB call) makes the backend peer service
208+
# pipeline map that client's host to the import span's service.
209+
parent = self.trace_ctx if root_node.context else cold_start_span
206210
self.trace_tree(root_node, parent)
207211
self.finish_span(cold_start_span, cold_start_span_end_time_ns)
208212

‎scripts/check_layer_size.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# Compares layer size to threshold, and fails if below that threshold
99

1010
set -e
11-
MAX_LAYER_COMPRESSED_SIZE_KB=$(expr 9 \* 1024 + 128) # 9344 KB
11+
MAX_LAYER_COMPRESSED_SIZE_KB=$(expr 10 \* 1024) # 10240 KB
1212
MAX_LAYER_UNCOMPRESSED_SIZE_KB=$(expr 25 \* 1024) # 25600 KB
1313

1414

‎tests/test_cold_start.py‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,45 @@ def handler(event, context):
325325
assert import_span.trace_id == function_span.trace_id
326326
assert load_span is not None
327327
assert load_span.trace_id == function_span.trace_id
328+
329+
330+
def test_lazy_loaded_package_imports_inside_client_span(monkeypatch):
331+
spans = []
332+
333+
def finish(span):
334+
spans.append(span)
335+
336+
monkeypatch.setattr(wrapper.tracer, "_on_span_finish", finish)
337+
monkeypatch.setattr(wrapper, "is_new_sandbox", lambda: True)
338+
monkeypatch.setattr("datadog_lambda.config.Config.trace_enabled", True)
339+
monkeypatch.setenv(
340+
"DD_COLD_START_TRACE_SKIP_LIB", "ddtrace.contrib.logging,datadog_lambda.wrapper"
341+
)
342+
monkeypatch.setenv("DD_MIN_COLD_START_DURATION", "0")
343+
# ensure the import below is not served from the module cache
344+
monkeypatch.delitem(modules, "colorsys", raising=False)
345+
346+
@wrapper.datadog_lambda_wrapper
347+
def handler(event, context):
348+
# e.g. botocore lazily importing modules on the first DynamoDB call
349+
with wrapper.tracer.trace("dynamodb.command", service="aws.dynamodb") as span:
350+
span.set_tag("span.kind", "client")
351+
import colorsys # noqa: F401
352+
353+
handler({}, get_mock_context())
354+
355+
function_span = client_span = import_span = None
356+
for span in spans:
357+
if span.resource == "colorsys":
358+
import_span = span
359+
elif span.name == "aws.lambda":
360+
function_span = span
361+
elif span.name == "dynamodb.command":
362+
client_span = span
363+
364+
assert function_span is not None
365+
assert client_span is not None
366+
assert import_span is not None
367+
assert import_span.parent_id == function_span.span_id
368+
assert import_span.parent_id != client_span.span_id
369+
assert import_span.trace_id == function_span.trace_id

0 commit comments

Comments
 (0)