Skip to content

Commit 1fac0fa

Browse files
committed
Fix patching for integration tests
1 parent aff095b commit 1fac0fa

10 files changed

+87
-44
lines changed

datadog_lambda/patch.py

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010

1111
from wrapt import wrap_function_wrapper as wrap
1212
from wrapt.importer import when_imported
13+
from ddtrace import patch_all as patch_all_dd
1314

14-
from datadog_lambda.tracing import get_dd_trace_context
15+
from datadog_lambda.tracing import (
16+
get_dd_trace_context,
17+
dd_tracing_enabled,
18+
)
1519

1620
logger = logging.getLogger(__name__)
1721

@@ -24,15 +28,31 @@
2428

2529
_httplib_patched = False
2630
_requests_patched = False
31+
_integration_tests_patched = False
2732

2833

2934
def patch_all():
3035
"""
31-
Patch the widely-used HTTP clients to automatically inject
32-
Datadog trace context.
36+
Patch third-party libraries for tracing.
3337
"""
34-
_patch_httplib()
35-
_ensure_patch_requests()
38+
_patch_for_integration_tests()
39+
40+
if dd_tracing_enabled:
41+
patch_all_dd()
42+
else:
43+
_patch_httplib()
44+
_ensure_patch_requests()
45+
46+
47+
def _patch_for_integration_tests():
48+
"""
49+
Patch `requests` to log the outgoing requests for integration tests.
50+
"""
51+
global _integration_tests_patched
52+
is_in_tests = os.environ.get("DD_INTEGRATION_TEST", "false").lower() == "true"
53+
if not _integration_tests_patched and is_in_tests:
54+
wrap("requests", "Session.send", _log_request)
55+
_integration_tests_patched = True
3656

3757

3858
def _patch_httplib():
@@ -89,10 +109,6 @@ def _wrap_requests_request(func, instance, args, kwargs):
89109
else:
90110
kwargs["headers"] = context
91111

92-
# If we're in an integration test, log the HTTP requests made
93-
if os.environ.get("DD_INTEGRATION_TEST", "false").lower() == "true":
94-
_print_request_string(args, kwargs)
95-
96112
return func(*args, **kwargs)
97113

98114

@@ -112,33 +128,28 @@ def _wrap_httplib_request(func, instance, args, kwargs):
112128
return func(*args, **kwargs)
113129

114130

115-
def _print_request_string(args, kwargs):
131+
def _log_request(func, instance, args, kwargs):
132+
request = kwargs.get("request") or args[0]
133+
_print_request_string(request)
134+
return func(*args, **kwargs)
135+
136+
137+
def _print_request_string(request):
116138
"""Print the request so that it can be checked in integration tests
117139
118140
Only used by integration tests.
119141
"""
120-
# Normalizes the different ways args can be passed to a request
121-
# to prevent test flakiness
122-
method = None
123-
if len(args) > 0:
124-
method = args[0]
125-
else:
126-
method = kwargs.get("method", "").upper()
127-
128-
url = None
129-
if len(args) > 1:
130-
url = args[1]
131-
else:
132-
url = kwargs.get("url")
142+
method = request.method
143+
url = request.url
133144

134145
# Sort the datapoints POSTed by their name so that snapshots always align
135-
data = kwargs.get("data", "{}")
146+
data = request.body or "{}"
136147
data_dict = json.loads(data)
137148
data_dict.get("series", []).sort(key=lambda series: series.get("metric"))
138149
sorted_data = json.dumps(data_dict)
139150

140151
# Sort headers to prevent any differences in ordering
141-
headers = kwargs.get("headers", {})
152+
headers = request.headers or {}
142153
sorted_headers = sorted(
143154
"{}:{}".format(key, value) for key, value in headers.items()
144155
)

datadog_lambda/wrapper.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
set_dd_trace_py_root,
2323
create_function_execution_span,
2424
)
25-
from ddtrace import patch_all as patch_all_dd
2625

2726
logger = logging.getLogger(__name__)
2827

@@ -93,12 +92,9 @@ def __init__(self, func):
9392
if self.logs_injection:
9493
inject_correlation_ids()
9594

96-
if not dd_tracing_enabled:
97-
# When using dd_trace_py it will patch all the http clients for us,
98-
# Patch HTTP clients to propagate Datadog trace context
99-
patch_all()
100-
else:
101-
patch_all_dd()
95+
# Patch third-party libraries for tracing
96+
patch_all()
97+
10298
logger.debug("datadog_lambda_wrapper initialized")
10399
except Exception:
104100
traceback.print_exc()

tests/integration/snapshots/logs/http-requests_python27.log

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
START RequestId: XXXX Version: $LATEST
22
{"e": XXXX, "m": "aws.lambda.enhanced.invocations", "t": ["region:us-east-1", "account_id:XXXX", "functionname:integration-tester-dev-http-requests_python27", "cold_start:true", "memorysize:1024", "runtime:python2.7", "dd_lambda_layer:datadog-python27_2.XX.0"], "v": 1}
3+
HTTP GET https://ip-ranges.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
4+
HTTP GET https://ip-ranges.datadoghq.eu/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
5+
HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Length:460", "Content-Type:application/json", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python27_2.XX.0"], "metric": "hello.dog", "interval": 10, "host": null, "points": [[XXXX, [1.0]]], "device": null, "type": "distribution"}, {"tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python27_2.XX.0"], "metric": "tests.integration.count", "interval": 10, "host": null, "points": [[XXXX, [21.0]]], "device": null, "type": "distribution"}]}
36
{"traces": [[{"resource": "integration-tester-dev-http-requests_python27", "name": "aws.lambda", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_sampling_priority_v1": 1, "system.pid": XXXX, "_dd.agent_psr": 1.0}, "parent_id": "XXXX", "meta": {"function_arn": "arn:aws:lambda:us-east-1:601427279990:function:integration-tester-dev-http-requests_python27", "resource_names": "integration-tester-dev-http-requests_python27", "cold_start": "true", "_dd.origin": "lambda", "_dd.parent_source": "xray", "request_id": "XXXX"}, "error": 0, "duration": XXXX, "type": "serverless", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://ip-ranges.datadoghq.com/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://ip-ranges.datadoghq.eu/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "202", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "_dd.origin": "lambda", "http.method": "POST"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}]]}
47
END RequestId: XXXX
58
REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms
69
XRAY TraceId: XXXX SegmentId: XXXX Sampled: true
710
START RequestId: XXXX Version: $LATEST
811
{"e": XXXX, "m": "aws.lambda.enhanced.invocations", "t": ["region:us-east-1", "account_id:XXXX", "functionname:integration-tester-dev-http-requests_python27", "cold_start:false", "memorysize:1024", "runtime:python2.7", "dd_lambda_layer:datadog-python27_2.XX.0"], "v": 1}
12+
HTTP GET https://ip-ranges.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
13+
HTTP GET https://ip-ranges.datadoghq.eu/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
14+
HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Length:460", "Content-Type:application/json", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python27_2.XX.0"], "metric": "hello.dog", "interval": 10, "host": null, "points": [[XXXX, [1.0]]], "device": null, "type": "distribution"}, {"tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python27_2.XX.0"], "metric": "tests.integration.count", "interval": 10, "host": null, "points": [[XXXX, [21.0]]], "device": null, "type": "distribution"}]}
915
{"traces": [[{"resource": "integration-tester-dev-http-requests_python27", "name": "aws.lambda", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_sampling_priority_v1": 1, "system.pid": XXXX, "_dd.agent_psr": 1.0}, "parent_id": "XXXX", "meta": {"function_arn": "arn:aws:lambda:us-east-1:601427279990:function:integration-tester-dev-http-requests_python27", "resource_names": "integration-tester-dev-http-requests_python27", "cold_start": "false", "_dd.origin": "lambda", "_dd.parent_source": "xray", "request_id": "XXXX"}, "error": 0, "duration": XXXX, "type": "serverless", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://ip-ranges.datadoghq.com/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://ip-ranges.datadoghq.eu/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "202", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "_dd.origin": "lambda", "http.method": "POST"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}]]}
1016
END RequestId: XXXX
1117
REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB
1218
XRAY TraceId: XXXX SegmentId: XXXX Sampled: true
1319
START RequestId: XXXX Version: $LATEST
1420
{"e": XXXX, "m": "aws.lambda.enhanced.invocations", "t": ["region:us-east-1", "account_id:XXXX", "functionname:integration-tester-dev-http-requests_python27", "cold_start:false", "memorysize:1024", "runtime:python2.7", "dd_lambda_layer:datadog-python27_2.XX.0"], "v": 1}
21+
HTTP GET https://ip-ranges.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
22+
HTTP GET https://ip-ranges.datadoghq.eu/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
23+
HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "Content-Length:460", "Content-Type:application/json", "User-Agent:python-requests/2.23.0", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {"series": [{"tags": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python27_2.XX.0"], "metric": "hello.dog", "interval": 10, "host": null, "points": [[XXXX, [1.0]]], "device": null, "type": "distribution"}, {"tags": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python27_2.XX.0"], "metric": "tests.integration.count", "interval": 10, "host": null, "points": [[XXXX, [21.0]]], "device": null, "type": "distribution"}]}
1524
{"traces": [[{"resource": "integration-tester-dev-http-requests_python27", "name": "aws.lambda", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_sampling_priority_v1": 1, "system.pid": XXXX, "_dd.agent_psr": 1.0}, "parent_id": "XXXX", "meta": {"function_arn": "arn:aws:lambda:us-east-1:601427279990:function:integration-tester-dev-http-requests_python27", "resource_names": "integration-tester-dev-http-requests_python27", "cold_start": "false", "_dd.origin": "lambda", "_dd.parent_source": "xray", "request_id": "XXXX"}, "error": 0, "duration": XXXX, "type": "serverless", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://ip-ranges.datadoghq.com/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://ip-ranges.datadoghq.eu/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "202", "http.url": "https://api.datadoghq.com/api/v1/distribution_points", "_dd.origin": "lambda", "http.method": "POST"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}]]}
1625
END RequestId: XXXX
1726
REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB

0 commit comments

Comments
 (0)