Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions datadog_lambda/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -977,16 +977,12 @@ def process_injected_data(event, request_time_epoch_ms, args, tags):
start_time_ns = int(
injected_authorizer_data.get(Headers.Parent_Span_Finish_Time)
)
finish_time_ns = (
request_time_epoch_ms
+ (
int(
event["requestContext"]["authorizer"].get(
"integrationLatency", 0
)
)
)
) * 1e6
integration_latency = int(
event["requestContext"]["authorizer"].get("integrationLatency", 0)
)
finish_time_ns = max(
start_time_ns, (request_time_epoch_ms + integration_latency) * 1e6
)
upstream_authorizer_span = insert_upstream_authorizer_span(
args, tags, start_time_ns, finish_time_ns
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"requestContext": {
"resourceId": "0et54l",
"authorizer": {
"_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTM0Nzg3MDU5OTU3OTcyMjEyMDkiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICI4NDcxMjg4MjYzMzg0MjE2ODk2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjMyOTUwMjE4MjcuNTIxLCAieC1kYXRhZG9nLWF1dGhvcml6aW5nLXJlcXVlc3RpZCI6ICJhYmMxMjMifQ==",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
   "x-datadog-trace-id":"13478705995797221209",
   "x-datadog-parent-id":"8471288263384216896",
   "x-datadog-sampling-priority":"1",
   "x-datadog-parent-span-finish-time":1663295021827.521,
   "x-datadog-authorizing-requestid":"abc123"
}

"_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTM0Nzg3MDU5OTU3OTcyMjEyMDkiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICI4NDcxMjg4MjYzMzg0MjE2ODk2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjMyOTUwMjE4Mjc1MjEwMDAsICJ4LWRhdGFkb2ctYXV0aG9yaXppbmctcmVxdWVzdGlkIjogImFiYzEyMyJ9",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
   "x-datadog-trace-id":"13478705995797221209",
   "x-datadog-parent-id":"8471288263384216896",
   "x-datadog-sampling-priority":"1",
   "x-datadog-parent-span-finish-time":1663295021827521000,
   "x-datadog-authorizing-requestid":"abc123"
}

"scope": "this is just a string",
"principalId": "foo",
"integrationLatency": 1897
Expand Down
32 changes: 32 additions & 0 deletions tests/test_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2408,6 +2408,38 @@ def test_create_inferred_span(mock_span_finish, source, expect):
assert mock_span_finish.call_count == 0


@patch("ddtrace.trace.Span.finish", autospec=True)
def test_authorizer_span_no_negative_duration_when_clock_skew(mock_span_finish):
"""
Simulate the case where requestTimeEpoch + integrationLatency < parentSpanFinishTime
(i.e., API Gateway's reported end is before the authorizer lambda's self-reported finish).
This 1ms discrepancy would produce a negative duration.
"""
with open(f"{event_samples}authorizer-request-api-gateway-v1.json") as f:
event = json.load(f)

authorizer_ctx = json.loads(
base64.b64decode(event["requestContext"]["authorizer"]["_datadog"])
)
parent_finish_time_ns = authorizer_ctx["x-datadog-parent-span-finish-time"]
request_time_epoch_ms = event["requestContext"]["requestTimeEpoch"]
# Set integrationLatency 1ms below the parent span's finish time to simulate clock skew.
event["requestContext"]["authorizer"]["integrationLatency"] = (
parent_finish_time_ns // 1_000_000 - request_time_epoch_ms - 1
)

ctx = get_mock_context(aws_request_id="123")
create_inferred_span(event, ctx)

args = mock_span_finish.call_args_list[0].args
authorizer_span, finish_time = args[0], args[1]

assert finish_time >= authorizer_span.start, (
f"Authorizer span has negative duration: "
f"finish_time={finish_time} < start={authorizer_span.start}"
)


class TestInferredSpans(unittest.TestCase):
@patch("datadog_lambda.tracing.submit_errors_metric")
def test_mark_trace_as_error_for_5xx_responses_getting_400_response_code(
Expand Down
Loading