Skip to content

Commit dd5d86b

Browse files
[SVLS-5265] S3 Event Handler Span Pointers
1 parent d97d9bb commit dd5d86b

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

datadog_lambda/span_pointers.py

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from itertools import chain
2+
from ddtrace._trace.utils_botocore.span_pointers import _aws_s3_object_span_pointer_description
3+
from ddtrace._trace._span_pointer import _SpanPointerDirection
4+
from ddtrace._trace._span_pointer import _SpanPointerDescription
5+
from datadog_lambda.trigger import EventTypes
6+
import logging
7+
8+
9+
logger = logging.getLogger(__name__)
10+
11+
12+
def calculate_span_pointers(
13+
event_source,
14+
event,
15+
) -> list[_SpanPointerDescription]:
16+
if event_source.equals(EventTypes.S3):
17+
return _calculate_s3_span_pointers_for_event(event)
18+
19+
return []
20+
21+
22+
def _calculate_s3_span_pointers_for_event(event) -> list[_SpanPointerDescription]:
23+
# Example event:
24+
# https://docs.aws.amazon.com/lambda/latest/dg/with-s3.html
25+
26+
return list(
27+
chain.from_iterable(
28+
_calculate_s3_span_pointers_for_event_record(record)
29+
for record in event.get("Records", [])
30+
)
31+
)
32+
33+
34+
def _calculate_s3_span_pointers_for_event_record(record) -> list[_SpanPointerDescription]:
35+
# Event types:
36+
# https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html
37+
38+
if record.get("eventName").startswith("ObjectCreated:"):
39+
s3_information = record.get("s3", None)
40+
if s3_information is not None:
41+
return _calculate_s3_span_pointers_for_object_created_s3_information(s3_information)
42+
43+
return []
44+
45+
46+
def _calculate_s3_span_pointers_for_object_created_s3_information(s3_information) -> list[_SpanPointerDescription]:
47+
try:
48+
bucket = s3_information["bucket"]["name"]
49+
key = s3_information["object"]["key"]
50+
etag = s3_information["object"]["eTag"]
51+
52+
except KeyError as e:
53+
logger.warning(
54+
"missing s3 information required to make a span pointer: %s",
55+
str(e),
56+
)
57+
return []
58+
59+
try:
60+
return [
61+
_aws_s3_object_span_pointer_description(
62+
pointer_direction=_SpanPointerDirection.UPSTREAM,
63+
bucket=bucket,
64+
key=key,
65+
etag=etag,
66+
)
67+
]
68+
69+
except Exception as e:
70+
logger.warning(
71+
"failed to generate S3 span pointer: %s",
72+
str(e),
73+
)
74+
return []

datadog_lambda/tracing.py

+9
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,7 @@ def create_function_execution_span(
12591259
merge_xray_traces,
12601260
trigger_tags,
12611261
parent_span=None,
1262+
span_pointers=None,
12621263
):
12631264
tags = None
12641265
if context:
@@ -1296,6 +1297,14 @@ def create_function_execution_span(
12961297
span.set_tags(tags)
12971298
if parent_span:
12981299
span.parent_id = parent_span.span_id
1300+
if span_pointers:
1301+
for span_pointer_description in span_pointers:
1302+
span._add_span_pointer(
1303+
pointer_kind=span_pointer_description.pointer_kind,
1304+
pointer_direction=span_pointer_description.pointer_direction,
1305+
pointer_hash=span_pointer_description.pointer_hash,
1306+
extra_attributes=span_pointer_description.extra_attributes,
1307+
)
12991308
return span
13001309

13011310

datadog_lambda/wrapper.py

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
)
3131
from datadog_lambda.module_name import modify_module_name
3232
from datadog_lambda.patch import patch_all
33+
from datadog_lambda.span_pointers import calculate_span_pointers
3334
from datadog_lambda.tracing import (
3435
extract_dd_trace_context,
3536
create_dd_dummy_metadata_subsegment,
@@ -315,6 +316,7 @@ def _before(self, event, context):
315316
self.merge_xray_traces,
316317
self.trigger_tags,
317318
parent_span=self.inferred_span,
319+
span_pointers=calculate_span_pointers(event_source, event),
318320
)
319321
else:
320322
set_correlation_ids()

0 commit comments

Comments
 (0)