Skip to content

Commit fc9a93a

Browse files
authored
[SLS-1683] Add sync/async tag and set inferred span end time based on value (#195)
* Add sync/async tag to inferred spans * End inferred span based on sync/async tag * Update tests * Fix issue with comparison * Fix small issues * Update integration test snapshots
1 parent 19db736 commit fc9a93a

13 files changed

+259
-77
lines changed

datadog_lambda/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,6 @@ class XrayDaemon(object):
4141
XRAY_TRACE_ID_HEADER_NAME = "_X_AMZN_TRACE_ID"
4242
XRAY_DAEMON_ADDRESS = "AWS_XRAY_DAEMON_ADDRESS"
4343
FUNCTION_NAME_HEADER_NAME = "AWS_LAMBDA_FUNCTION_NAME"
44+
45+
46+
IS_ASYNC_TAG = "is_async"

datadog_lambda/tracing.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
import logging
77
import os
88
import json
9+
from datetime import datetime, timezone
910

1011
from datadog_lambda.constants import (
1112
SamplingPriority,
1213
TraceHeader,
1314
TraceContextSource,
1415
XrayDaemon,
16+
IS_ASYNC_TAG,
1517
)
1618
from datadog_lambda.xray import (
1719
send_segment,
@@ -27,7 +29,6 @@
2729
EventTypes,
2830
EventSubtypes,
2931
)
30-
from datetime import datetime, timezone
3132

3233
logger = logging.getLogger(__name__)
3334

@@ -436,6 +437,14 @@ def create_inferred_span(event, context):
436437
return None
437438

438439

440+
def is_api_gateway_invocation_async(event):
441+
return (
442+
"headers" in event
443+
and "X-Amz-Invocation-Type" in event["headers"]
444+
and event["headers"]["X-Amz-Invocation-Type"] == "Event"
445+
)
446+
447+
439448
def create_inferred_span_from_api_gateway_websocket_event(event, context):
440449
domain = event["requestContext"]["domainName"]
441450
endpoint = event["requestContext"]["routeKey"]
@@ -448,6 +457,7 @@ def create_inferred_span_from_api_gateway_websocket_event(event, context):
448457
"request_id": context.aws_request_id,
449458
"connection_id": event["requestContext"]["connectionId"],
450459
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
460+
IS_ASYNC_TAG: is_api_gateway_invocation_async(event),
451461
}
452462
request_time_epoch = event["requestContext"]["requestTimeEpoch"]
453463
args = {
@@ -474,6 +484,7 @@ def create_inferred_span_from_api_gateway_event(event, context):
474484
"resource_names": domain + path,
475485
"request_id": context.aws_request_id,
476486
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
487+
IS_ASYNC_TAG: is_api_gateway_invocation_async(event),
477488
}
478489
request_time_epoch = event["requestContext"]["requestTimeEpoch"]
479490
args = {
@@ -500,6 +511,7 @@ def create_inferred_span_from_http_api_event(event, context):
500511
"resource_names": domain + path,
501512
"request_id": context.aws_request_id,
502513
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
514+
IS_ASYNC_TAG: is_api_gateway_invocation_async(event),
503515
}
504516
request_time_epoch = event["requestContext"]["timeEpoch"]
505517
args = {
@@ -522,6 +534,7 @@ def create_inferred_span_from_sqs_event(event, context):
522534
"service.name": "sqs",
523535
"resource_names": queue_name,
524536
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
537+
IS_ASYNC_TAG: True,
525538
}
526539
request_time_epoch = event_record["attributes"]["SentTimestamp"]
527540
args = {
@@ -544,6 +557,7 @@ def create_inferred_span_from_sns_event(event, context):
544557
"service.name": "sns",
545558
"resource_names": topic_name,
546559
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
560+
IS_ASYNC_TAG: True,
547561
}
548562
sns_dt_format = "%Y-%m-%dT%H:%M:%S.%fZ"
549563
timestamp = event_record["Sns"]["Timestamp"]
@@ -569,6 +583,7 @@ def create_inferred_span_from_kinesis_event(event, context):
569583
"service.name": "kinesis",
570584
"resource_names": stream_name,
571585
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
586+
IS_ASYNC_TAG: True,
572587
}
573588
request_time_epoch = event_record["kinesis"]["approximateArrivalTimestamp"]
574589

@@ -592,6 +607,7 @@ def create_inferred_span_from_dynamodb_event(event, context):
592607
"service.name": "dynamodb",
593608
"resource_names": table_name,
594609
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
610+
IS_ASYNC_TAG: True,
595611
}
596612
request_time_epoch = event_record["dynamodb"]["ApproximateCreationDateTime"]
597613

@@ -615,6 +631,7 @@ def create_inferred_span_from_s3_event(event, context):
615631
"service.name": "s3",
616632
"resource_names": bucket_name,
617633
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
634+
IS_ASYNC_TAG: True,
618635
}
619636
dt_format = "%Y-%m-%dT%H:%M:%S.%fZ"
620637
timestamp = event_record["eventTime"]
@@ -639,6 +656,7 @@ def create_inferred_span_from_eventbridge_event(event, context):
639656
"service.name": "eventbridge",
640657
"resource_names": source,
641658
SPAN_TYPE_TAG: SPAN_TYPE_INFERRED,
659+
IS_ASYNC_TAG: True,
642660
}
643661
dt_format = "%Y-%m-%dT%H:%M:%SZ"
644662
timestamp = event["time"]

datadog_lambda/wrapper.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010

1111
from datadog_lambda.extension import should_use_extension, flush_extension
1212
from datadog_lambda.cold_start import set_cold_start, is_cold_start
13-
from datadog_lambda.constants import XraySubsegment, TraceContextSource
13+
from datadog_lambda.constants import (
14+
XraySubsegment,
15+
TraceContextSource,
16+
IS_ASYNC_TAG,
17+
)
1418
from datadog_lambda.metric import (
1519
flush_stats,
1620
submit_invocations_metric,
@@ -201,10 +205,15 @@ def _after(self, event, context):
201205
if status_code:
202206
self.span.set_tag("http.status_code", status_code)
203207
self.span.finish()
208+
204209
if self.inferred_span:
205210
if status_code:
206211
self.inferred_span.set_tag("http.status_code", status_code)
207-
self.inferred_span.finish()
212+
213+
if self.inferred_span.get_tag(IS_ASYNC_TAG) == "True" and self.span:
214+
self.inferred_span.finish(finish_time=self.span.start)
215+
else:
216+
self.inferred_span.finish()
208217

209218
if not self.flush_to_log or should_use_extension:
210219
flush_stats()
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
{
2+
"resource": "/http/get",
3+
"path": "/http/get",
4+
"httpMethod": "GET",
5+
"headers": {
6+
"Accept": "*/*",
7+
"CloudFront-Forwarded-Proto": "https",
8+
"CloudFront-Is-Desktop-Viewer": "true",
9+
"CloudFront-Is-Mobile-Viewer": "false",
10+
"CloudFront-Is-SmartTV-Viewer": "false",
11+
"CloudFront-Is-Tablet-Viewer": "false",
12+
"CloudFront-Viewer-Country": "US",
13+
"Host": "lgxbo6a518.execute-api.sa-east-1.amazonaws.com",
14+
"User-Agent": "curl/7.64.1",
15+
"Via": "2.0 a1882a601559755135741e91a9f86c28.cloudfront.net (CloudFront)",
16+
"X-Amz-Cf-Id": "dHMNSBrMT0Xjg3rtMrI0Ie9BDg3D_OIPoj7m0mTuIOpTujrU0Ob8_A==",
17+
"X-Amzn-Trace-Id": "Root=1-613a4da3-5012576973e2e5670d4c549a",
18+
"X-Forwarded-For": "38.122.226.210, 70.132.52.143",
19+
"X-Forwarded-Port": "443",
20+
"X-Forwarded-Proto": "https",
21+
"X-Amz-Invocation-Type": "Event"
22+
},
23+
"multiValueHeaders": {
24+
"Accept": [
25+
"*/*"
26+
],
27+
"CloudFront-Forwarded-Proto": [
28+
"https"
29+
],
30+
"CloudFront-Is-Desktop-Viewer": [
31+
"true"
32+
],
33+
"CloudFront-Is-Mobile-Viewer": [
34+
"false"
35+
],
36+
"CloudFront-Is-SmartTV-Viewer": [
37+
"false"
38+
],
39+
"CloudFront-Is-Tablet-Viewer": [
40+
"false"
41+
],
42+
"CloudFront-Viewer-Country": [
43+
"US"
44+
],
45+
"Host": [
46+
"lgxbo6a518.execute-api.sa-east-1.amazonaws.com"
47+
],
48+
"User-Agent": [
49+
"curl/7.64.1"
50+
],
51+
"Via": [
52+
"2.0 a1882a601559755135741e91a9f86c28.cloudfront.net (CloudFront)"
53+
],
54+
"X-Amz-Cf-Id": [
55+
"dHMNSBrMT0Xjg3rtMrI0Ie9BDg3D_OIPoj7m0mTuIOpTujrU0Ob8_A=="
56+
],
57+
"X-Amzn-Trace-Id": [
58+
"Root=1-613a4da3-5012576973e2e5670d4c549a"
59+
],
60+
"X-Forwarded-For": [
61+
"38.122.226.210, 70.132.52.143"
62+
],
63+
"X-Forwarded-Port": [
64+
"443"
65+
],
66+
"X-Forwarded-Proto": [
67+
"https"
68+
]
69+
},
70+
"queryStringParameters": null,
71+
"multiValueQueryStringParameters": null,
72+
"pathParameters": null,
73+
"stageVariables": null,
74+
"requestContext": {
75+
"resourceId": "8ajqil",
76+
"resourcePath": "/http/get",
77+
"httpMethod": "GET",
78+
"extendedRequestId": "FaERiG1RGjQFb6g=",
79+
"requestTime": "09/Sep/2021:18:08:35 +0000",
80+
"path": "/dev/http/get",
81+
"accountId": "601427279990",
82+
"protocol": "HTTP/1.1",
83+
"stage": "dev",
84+
"domainPrefix": "lgxbo6a518",
85+
"requestTimeEpoch": 1631210915251,
86+
"requestId": "7bf3b161-f698-432c-a639-6fef8b445137",
87+
"identity": {
88+
"cognitoIdentityPoolId": null,
89+
"accountId": null,
90+
"cognitoIdentityId": null,
91+
"caller": null,
92+
"sourceIp": "38.122.226.210",
93+
"principalOrgId": null,
94+
"accessKey": null,
95+
"cognitoAuthenticationType": null,
96+
"cognitoAuthenticationProvider": null,
97+
"userArn": null,
98+
"userAgent": "curl/7.64.1",
99+
"user": null
100+
},
101+
"domainName": "lgxbo6a518.execute-api.sa-east-1.amazonaws.com",
102+
"apiId": "lgxbo6a518"
103+
},
104+
"body": null,
105+
"isBase64Encoded": false
106+
}

0 commit comments

Comments
 (0)