Skip to content

Commit 1b3599b

Browse files
astuyvejtappa
andauthored
Feat: Add ability to tag Lambda request and response payloads for 2.7… (#180)
* Update expected breaking change date (#114) * Feat: Add ability to tag Lambda request and response payloads for 2.7 and 3.x * feat: fix names of functions. Add tests for redacted keys as well as deeply tagging a json object * feat: test coverage for should_try_string across py versions * feat: add black formatter, used in ci, to vscode settings * lint: run black * feat: add integration test support Co-authored-by: Jorie Helwig <[email protected]>
1 parent 2b75247 commit 1b3599b

18 files changed

+203
-48
lines changed

.vscode/settings.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"python.pythonPath": "/usr/local/bin/python3"
3-
}
2+
"python.pythonPath": "/usr/local/bin/python3",
3+
"python.formatting.provider": "black"
4+
}

CONTRIBUTING.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
# Contributing
22

3-
We love pull requests. For new features, consider opening an issue to discuss the idea first. When you're ready to open a pull requset, here's a quick guide.
3+
We love pull requests. For new features, consider opening an issue to discuss the idea first. When you're ready to open a pull request, here's a quick guide.
44

55
1. Fork, clone and branch off `main`:
6-
```bash
7-
git clone [email protected]:<your-username>/datadog-lambda-python.git
8-
git checkout -b <my-branch>
9-
```
10-
1. Make your changes. Ensure your code is compatible with both Python 2.7 and 3.X.
6+
```bash
7+
git clone [email protected]:<your-username>/datadog-lambda-python.git
8+
git checkout -b <my-branch>
9+
```
10+
1. Make your changes. Ensure your code is compatible with both Python 2.7 and 3.X.
1111
1. Test your Lambda function against the locally modified version of Datadog Lambda library.
12-
* The easiest approach is to create a soft link of the `datadog_lambda` folder in your project's root. Note, this only overrides the `datadog_lambda` module, and you still need to install the `datadog_lambda` package or the Lambda layer to have the required dependencies.
12+
13+
- The easiest approach is to create a soft link of the `datadog_lambda` folder in your project's root. Note, this only overrides the `datadog_lambda` module, and you still need to install the `datadog_lambda` package or the Lambda layer to have the required dependencies.
1314

1415
```bash
1516
ln -s /PATH/TO/datadog-lambda-python/datadog_lambda /PATH/TO/MY/PROJECT
1617
```
17-
* Another option is to install the `datadog_lambda` module from the local folder. E.g., add `/PATH/TO/datadog-lambda-python/` to your `requirements.txt`. This approach only work in a Linux environment, because the dependency `ddtrace` utilizes the native C extension.
18-
* You can also build and publish a Lambda layer to your own AWS account and use it for testing.
18+
19+
- Another option is to install the `datadog_lambda` module from the local folder. E.g., add `/PATH/TO/datadog-lambda-python/` to your `requirements.txt`. This approach only work in a Linux environment, because the dependency `ddtrace` utilizes the native C extension.
20+
- You can also build and publish a Lambda layer to your own AWS account and use it for testing.
1921

2022
```bash
2123
# Build layers using docker
@@ -27,9 +29,9 @@ We love pull requests. For new features, consider opening an issue to discuss th
2729
```
2830

2931
1. Ensure the unit tests pass (install Docker if you haven't):
30-
```bash
31-
./scripts/run_tests.sh
32-
```
32+
```bash
33+
./scripts/run_tests.sh
34+
```
3335
1. Run the integration tests against your own AWS account and Datadog org (or ask a Datadog member to run):
3436
```bash
3537
BUILD_LAYERS=true DD_API_KEY=<your Datadog api key> ./scripts/run_integration_tests.sh

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
[![Slack](https://chat.datadoghq.com/badge.svg?bg=632CA6)](https://chat.datadoghq.com/)
77
[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/DataDog/datadog-lambda-python/blob/main/LICENSE)
88

9-
Datadog Lambda Library for Python (2.7, 3.6, 3.7, 3.8, and 3.9) enables enhanced Lambda metrics, distributed tracing, and custom metric submission from AWS Lambda functions.
9+
Datadog Lambda Library for Python (2.7, 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 **December 1, 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 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.
1212

1313
## Installation
1414

@@ -24,7 +24,7 @@ Check out the instructions for [submitting custom metrics from AWS Lambda functi
2424

2525
Once [installed](#installation), you should be able to view your function's traces in Datadog, and your function's logs should be automatically connected to the traces.
2626

27-
For additional details on trace collection, take a look at [collecting traces from AWS Lambda functions](https://docs.datadoghq.com/integrations/amazon_lambda/?tab=python#trace-collection).
27+
For additional details on trace collection, take a look at [collecting traces from AWS Lambda functions](https://docs.datadoghq.com/integrations/amazon_lambda/?tab=python#trace-collection).
2828

2929
For additional details on trace and log connection, see [connecting logs and traces](https://docs.datadoghq.com/tracing/connect_logs_and_traces/python/).
3030

datadog_lambda/tag_object.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Unless explicitly stated otherwise all files in this repository are licensed
2+
# under the Apache License Version 2.0.
3+
# This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
# Copyright 2021 Datadog, Inc.
5+
6+
import json
7+
import logging
8+
9+
redactable_keys = ["authorization", "x-authorization", "password", "token"]
10+
max_depth = 10
11+
logger = logging.getLogger(__name__)
12+
13+
14+
def tag_object(span, key, obj, depth=0):
15+
if depth >= max_depth:
16+
return
17+
else:
18+
depth += 1
19+
if obj is None:
20+
return span.set_tag(key, obj)
21+
if _should_try_string(obj):
22+
parsed = None
23+
try:
24+
parsed = json.loads(obj)
25+
return tag_object(span, key, parsed, depth)
26+
except ValueError:
27+
redacted = _redact_val(key, obj[0:5000])
28+
return span.set_tag(key, redacted)
29+
if isinstance(obj, int) or isinstance(obj, float):
30+
return span.set_tag(key, obj)
31+
if isinstance(obj, list):
32+
for k, v in enumerate(obj):
33+
formatted_key = "{}.{}".format(key, k)
34+
tag_object(span, formatted_key, v, depth)
35+
return
36+
if isinstance(obj, object):
37+
for k in obj:
38+
v = obj.get(k)
39+
formatted_key = "{}.{}".format(key, k)
40+
tag_object(span, formatted_key, v, depth)
41+
return
42+
43+
44+
def _should_try_string(obj):
45+
try:
46+
if isinstance(obj, str) or isinstance(obj, unicode):
47+
return True
48+
except NameError:
49+
if isinstance(obj, bytes):
50+
return True
51+
52+
return False
53+
54+
55+
def _redact_val(k, v):
56+
split_key = k.split(".").pop() or k
57+
if split_key in redactable_keys:
58+
return "redacted"
59+
return v

datadog_lambda/tracing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ def extract_dd_trace_context(event, lambda_context, extractor=None):
261261

262262
def get_dd_trace_context():
263263
"""
264-
Return the Datadog trace context to be propogated on the outgoing requests.
264+
Return the Datadog trace context to be propagated on the outgoing requests.
265265
266266
If the Lambda function is invoked by a Datadog-traced service, a Datadog
267267
trace context may already exist, and it should be used. Otherwise, use the

datadog_lambda/wrapper.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@
2828
create_function_execution_span,
2929
)
3030
from datadog_lambda.trigger import extract_trigger_tags, extract_http_status_code_tag
31+
from datadog_lambda.tag_object import tag_object
3132

3233
logger = logging.getLogger(__name__)
3334

35+
dd_capture_lambda_payload_enabled = (
36+
os.environ.get("DD_CAPTURE_LAMBDA_PAYLOAD", "false").lower() == "true"
37+
)
3438

3539
"""
3640
Usage:
@@ -186,6 +190,10 @@ def _after(self, event, context):
186190
flush_extension()
187191

188192
if self.span:
193+
if dd_capture_lambda_payload_enabled:
194+
tag_object(self.span, "function.request", event)
195+
tag_object(self.span, "function.response", self.response)
196+
189197
if status_code:
190198
self.span.set_tag("http.status_code", status_code)
191199
self.span.finish()

tests/integration/serverless.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ provider:
1616
DD_INTEGRATION_TEST: true
1717
DD_TRACE_ENABLED: true
1818
DD_API_KEY: ${env:DD_API_KEY}
19+
DD_CAPTURE_LAMBDA_PAYLOAD: true
1920
lambdaHashingVersion: 20201221
2021
timeout: 15
2122
deploymentBucket:

0 commit comments

Comments
 (0)