Skip to content

Commit 1ba7ceb

Browse files
agocsjtappahghotra
authored
Add extractor for Eventbridge context (#202)
* Update expected breaking change date (#114) * change inferred_span to _inferred_span * Add extractor for eventbridge trace context * Add another test to test eventbridge extraction * Get tracing.Literal for pythons that don't have it already * Add _datadog to eventbridge extractor * Update integration tests * Remove init complete and main start logs Co-authored-by: Jorie Helwig <[email protected]> Co-authored-by: Harvinder Ghotra <[email protected]>
1 parent 7b2adcf commit 1ba7ceb

14 files changed

+147
-77
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Datadog Lambda Library for Python (3.6, 3.7, 3.8, and 3.9) enables enhanced Lambda metrics, distributed tracing, and custom metric submission from AWS Lambda functions.
1010

11-
**IMPORTANT NOTE:** AWS Lambda is expected to receive a [breaking change](https://aws.amazon.com/blogs/compute/upcoming-changes-to-the-python-sdk-in-aws-lambda/) on **March 31, 2021**. If you are using Datadog Python Lambda layer version 7 or below, please upgrade to the latest.
11+
**IMPORTANT NOTE:** AWS Lambda is expected to recieve a [breaking change](https://aws.amazon.com/blogs/compute/upcoming-changes-to-the-python-sdk-in-aws-lambda/) on **March 31, 2021**. If you are using Datadog Python Lambda layer version 7 or below, please upgrade to the latest.
1212

1313
## Installation
1414

datadog_lambda/tracing.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
import os
88
import json
99
from datetime import datetime, timezone
10-
from typing import Optional, Literal, Dict
10+
from typing import Optional, Dict
11+
12+
try:
13+
from typing import Literal
14+
except ImportError:
15+
# Literal was added to typing in python 3.8
16+
from typing_extensions import Literal
1117

1218
from datadog_lambda.constants import (
1319
SamplingPriority,
@@ -227,6 +233,25 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context):
227233
return extract_context_from_lambda_context(lambda_context)
228234

229235

236+
def extract_context_from_eventbridge_event(event, lambda_context):
237+
"""
238+
Extract datadog trace context from an EventBridge message's Details.
239+
Details is often a weirdly escaped almost-JSON string. Here we have to correct for that.
240+
"""
241+
try:
242+
detail = event["detail"]
243+
dd_context = detail.get("_datadog")
244+
print(f"dd_context is {dd_context}")
245+
if not dd_context:
246+
return extract_context_from_lambda_context(lambda_context)
247+
trace_id = dd_context.get(TraceHeader.TRACE_ID)
248+
parent_id = dd_context.get(TraceHeader.PARENT_ID)
249+
sampling_priority = dd_context.get(TraceHeader.SAMPLING_PRIORITY)
250+
return trace_id, parent_id, sampling_priority
251+
except Exception:
252+
return extract_context_from_lambda_context(lambda_context)
253+
254+
230255
def extract_context_custom_extractor(extractor, event, lambda_context):
231256
"""
232257
Extract Datadog trace context using a custom trace extractor function
@@ -253,6 +278,7 @@ def extract_dd_trace_context(event, lambda_context, extractor=None):
253278
"""
254279
global dd_trace_context
255280
trace_context_source = None
281+
event_source = parse_event_source(event)
256282

257283
if extractor is not None:
258284
(
@@ -272,6 +298,12 @@ def extract_dd_trace_context(event, lambda_context, extractor=None):
272298
parent_id,
273299
sampling_priority,
274300
) = extract_context_from_sqs_or_sns_event_or_context(event, lambda_context)
301+
elif event_source.equals(EventTypes.EVENTBRIDGE):
302+
(
303+
trace_id,
304+
parent_id,
305+
sampling_priority,
306+
) = extract_context_from_eventbridge_event(event, lambda_context)
275307
else:
276308
trace_id, parent_id, sampling_priority = extract_context_from_lambda_context(
277309
lambda_context
@@ -775,7 +807,7 @@ def create_function_execution_span(
775807

776808

777809
class InferredSpanInfo(object):
778-
BASE_NAME = "inferred_span"
810+
BASE_NAME = "_inferred_span"
779811
SYNCHRONICITY = f"{BASE_NAME}.synchronicity"
780812
TAG_SOURCE = f"{BASE_NAME}.tag_source"
781813

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ wrapt = "^1.11.2"
2929
ddtrace = "^0.50.0"
3030
importlib_metadata = {version = "^1.0", python = "<3.8"}
3131
boto3 = { version = "^1.10.33", optional = true }
32+
typing_extensions = {version = "^4.0", python = "<3.8"}
3233
requests = { version ="^2.22.0", optional = true }
3334
nose2 = { version= "^0.9.1", optional = true }
3435
flake8 = { version = "^3.7.9", optional = true }

scripts/run_integration_tests.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,9 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do
212212
sed -E "s/(\"system\.pid\"\: )[0-9\.\-]+/\1\"XXXX\"/g" |
213213
sed -E "s/(\"runtime-id\"\: \")[a-z0-9\.\-]+/\1XXXX/g" |
214214
sed -E "s/(\"datadog_lambda\"\: \")([0-9]+\.[0-9]+\.[0-9])/\1X.X.X/g" |
215-
sed -E "s/(\"dd_trace\"\: \")([0-9]+\.[0-9]+\.[0-9])/\1X.X.X/g"
215+
sed -E "s/(\"dd_trace\"\: \")([0-9]+\.[0-9]+\.[0-9])/\1X.X.X/g" |
216+
sed -E "/init complete at epoch/d" |
217+
sed -E "/main started at epoch/d"
216218
)
217219

218220
if [ ! -f $function_snapshot_path ]; then

tests/event_samples/eventbridge-custom.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
"region": "sa-east-1",
99
"resources": [],
1010
"detail": {
11-
"foo": "bar"
11+
"foo": "bar",
12+
"_datadog": {
13+
"x-datadog-trace-id": "12345",
14+
"x-datadog-parent-id": "67890",
15+
"x-datadog-sampling-priority": "2"
16+
}
1217
}
1318
}

0 commit comments

Comments
 (0)