datadog_lambda 8.114.0__tar.gz → 8.118.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/PKG-INFO +4 -3
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/README.md +1 -1
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/__init__.py +1 -8
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/asm.py +2 -2
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/config.py +9 -6
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/metric.py +27 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/tag_object.py +1 -1
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/tracing.py +18 -5
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/trigger.py +2 -1
- datadog_lambda-8.118.0/datadog_lambda/version.py +1 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/wrapper.py +14 -2
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/pyproject.toml +3 -2
- datadog_lambda-8.114.0/datadog_lambda/version.py +0 -1
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/LICENSE +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/LICENSE-3rdparty.csv +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/NOTICE +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/api.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/cold_start.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/constants.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/dogstatsd.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/extension.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/handler.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/logger.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/module_name.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/patch.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/span_pointers.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/stats_writer.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/statsd_writer.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/tags.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/thread_stats_writer.py +0 -0
- {datadog_lambda-8.114.0 → datadog_lambda-8.118.0}/datadog_lambda/xray.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: datadog_lambda
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.118.0
|
|
4
4
|
Summary: The Datadog AWS Lambda Library
|
|
5
5
|
Home-page: https://github.com/DataDog/datadog-lambda-python
|
|
6
6
|
License: Apache-2.0
|
|
@@ -16,10 +16,11 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
20
|
Provides-Extra: dev
|
|
20
21
|
Requires-Dist: botocore (>=1.34.0,<2.0.0) ; extra == "dev"
|
|
21
22
|
Requires-Dist: datadog (>=0.51.0,<1.0.0)
|
|
22
|
-
Requires-Dist: ddtrace (>=3.
|
|
23
|
+
Requires-Dist: ddtrace (>=3.16.2,<3.19.0)
|
|
23
24
|
Requires-Dist: flake8 (>=5.0.4,<6.0.0) ; extra == "dev"
|
|
24
25
|
Requires-Dist: pytest (>=8.0.0,<9.0.0) ; extra == "dev"
|
|
25
26
|
Requires-Dist: pytest-benchmark (>=4.0,<5.0) ; extra == "dev"
|
|
@@ -37,7 +38,7 @@ Description-Content-Type: text/markdown
|
|
|
37
38
|
[](https://chat.datadoghq.com/)
|
|
38
39
|
[](https://github.com/DataDog/datadog-lambda-python/blob/main/LICENSE)
|
|
39
40
|
|
|
40
|
-
Datadog Lambda Library for Python (3.8, 3.9, 3.10, 3.11, 3.12, and 3.
|
|
41
|
+
Datadog Lambda Library for Python (3.8, 3.9, 3.10, 3.11, 3.12, 3.13, and 3.14) enables [enhanced Lambda metrics](https://docs.datadoghq.com/serverless/enhanced_lambda_metrics), [distributed tracing](https://docs.datadoghq.com/serverless/distributed_tracing), and [custom metric submission](https://docs.datadoghq.com/serverless/custom_metrics) from AWS Lambda functions.
|
|
41
42
|
|
|
42
43
|
## Installation
|
|
43
44
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://chat.datadoghq.com/)
|
|
7
7
|
[](https://github.com/DataDog/datadog-lambda-python/blob/main/LICENSE)
|
|
8
8
|
|
|
9
|
-
Datadog Lambda Library for Python (3.8, 3.9, 3.10, 3.11, 3.12, and 3.
|
|
9
|
+
Datadog Lambda Library for Python (3.8, 3.9, 3.10, 3.11, 3.12, 3.13, and 3.14) enables [enhanced Lambda metrics](https://docs.datadoghq.com/serverless/enhanced_lambda_metrics), [distributed tracing](https://docs.datadoghq.com/serverless/distributed_tracing), and [custom metric submission](https://docs.datadoghq.com/serverless/custom_metrics) from AWS Lambda functions.
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
+
import datadog_lambda.config # noqa: F401 needs to be imported before `ddtrace`
|
|
1
2
|
from datadog_lambda.cold_start import initialize_cold_start_tracing
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if os.environ.get("DD_INSTRUMENTATION_TELEMETRY_ENABLED") is None:
|
|
6
|
-
# Telemetry is required for Appsec Software Composition Analysis
|
|
7
|
-
os.environ["DD_INSTRUMENTATION_TELEMETRY_ENABLED"] = os.environ.get(
|
|
8
|
-
"DD_APPSEC_ENABLED", "false"
|
|
9
|
-
)
|
|
10
3
|
|
|
11
4
|
|
|
12
5
|
initialize_cold_start_tracing()
|
|
@@ -126,8 +126,8 @@ def asm_start_request(
|
|
|
126
126
|
|
|
127
127
|
request_ip = _get_request_header_client_ip(request_headers, peer_ip, True)
|
|
128
128
|
if request_ip is not None:
|
|
129
|
-
span.
|
|
130
|
-
span.
|
|
129
|
+
span.set_tag("http.client_ip", request_ip)
|
|
130
|
+
span.set_tag("network.client.ip", request_ip)
|
|
131
131
|
|
|
132
132
|
# Encode the parsed query and append it to reconstruct the original raw URI expected by AppSec.
|
|
133
133
|
if parsed_query:
|
|
@@ -82,12 +82,6 @@ class Config:
|
|
|
82
82
|
logs_injection = _get_env("DD_LOGS_INJECTION", "true", as_bool)
|
|
83
83
|
merge_xray_traces = _get_env("DD_MERGE_XRAY_TRACES", "false", as_bool)
|
|
84
84
|
|
|
85
|
-
telemetry_enabled = _get_env(
|
|
86
|
-
"DD_INSTRUMENTATION_TELEMETRY_ENABLED",
|
|
87
|
-
"false",
|
|
88
|
-
as_bool,
|
|
89
|
-
depends_on_tracing=True,
|
|
90
|
-
)
|
|
91
85
|
otel_enabled = _get_env("DD_TRACE_OTEL_ENABLED", "false", as_bool)
|
|
92
86
|
profiling_enabled = _get_env("DD_PROFILING_ENABLED", "false", as_bool)
|
|
93
87
|
llmobs_enabled = _get_env("DD_LLMOBS_ENABLED", "false", as_bool)
|
|
@@ -96,6 +90,7 @@ class Config:
|
|
|
96
90
|
"DD_DATA_STREAMS_ENABLED", "false", as_bool, depends_on_tracing=True
|
|
97
91
|
)
|
|
98
92
|
appsec_enabled = _get_env("DD_APPSEC_ENABLED", "false", as_bool)
|
|
93
|
+
sca_enabled = _get_env("DD_APPSEC_SCA_ENABLED", "false", as_bool)
|
|
99
94
|
|
|
100
95
|
is_gov_region = _get_env("AWS_REGION", "", lambda x: x.startswith("us-gov-"))
|
|
101
96
|
|
|
@@ -144,3 +139,11 @@ if config.is_gov_region or config.fips_mode_enabled:
|
|
|
144
139
|
"Python Lambda Layer FIPS mode is %s.",
|
|
145
140
|
"enabled" if config.fips_mode_enabled else "not enabled",
|
|
146
141
|
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
if (
|
|
145
|
+
"DD_INSTRUMENTATION_TELEMETRY_ENABLED" not in os.environ
|
|
146
|
+
and not config.sca_enabled
|
|
147
|
+
and not config.appsec_enabled
|
|
148
|
+
):
|
|
149
|
+
os.environ["DD_INSTRUMENTATION_TELEMETRY_ENABLED"] = "false"
|
|
@@ -214,6 +214,33 @@ def submit_errors_metric(lambda_context):
|
|
|
214
214
|
submit_enhanced_metric("errors", lambda_context)
|
|
215
215
|
|
|
216
216
|
|
|
217
|
+
def submit_batch_item_failures_metric(response, lambda_context):
|
|
218
|
+
"""Submit aws.lambda.enhanced.batch_item_failures metric with the count of batch item failures
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
response (dict): Lambda function response object
|
|
222
|
+
lambda_context (object): Lambda context dict passed to the function by AWS
|
|
223
|
+
"""
|
|
224
|
+
if not config.enhanced_metrics_enabled:
|
|
225
|
+
logger.debug(
|
|
226
|
+
"Not submitting batch_item_failures metric because enhanced metrics are disabled"
|
|
227
|
+
)
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
if not isinstance(response, dict):
|
|
231
|
+
return
|
|
232
|
+
|
|
233
|
+
batch_item_failures = response.get("batchItemFailures")
|
|
234
|
+
if batch_item_failures is not None and isinstance(batch_item_failures, list):
|
|
235
|
+
lambda_metric(
|
|
236
|
+
"aws.lambda.enhanced.batch_item_failures",
|
|
237
|
+
len(batch_item_failures),
|
|
238
|
+
timestamp=None,
|
|
239
|
+
tags=get_enhanced_metrics_tags(lambda_context),
|
|
240
|
+
force_async=True,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
|
|
217
244
|
def submit_dynamodb_stream_type_metric(event):
|
|
218
245
|
stream_view_type = (
|
|
219
246
|
event.get("Records", [{}])[0].get("dynamodb", {}).get("StreamViewType")
|
|
@@ -55,11 +55,6 @@ if config.otel_enabled:
|
|
|
55
55
|
logger = logging.getLogger(__name__)
|
|
56
56
|
|
|
57
57
|
dd_trace_context = None
|
|
58
|
-
if config.telemetry_enabled:
|
|
59
|
-
# Enable the telemetry client if the user has opted in
|
|
60
|
-
from ddtrace.internal.telemetry import telemetry_writer
|
|
61
|
-
|
|
62
|
-
telemetry_writer.enable()
|
|
63
58
|
|
|
64
59
|
propagator = HTTPPropagator()
|
|
65
60
|
|
|
@@ -209,6 +204,20 @@ def extract_context_from_http_event_or_context(
|
|
|
209
204
|
return context
|
|
210
205
|
|
|
211
206
|
|
|
207
|
+
def extract_context_from_request_header_or_context(event, lambda_context, event_source):
|
|
208
|
+
request = event.get("request")
|
|
209
|
+
if isinstance(request, (set, dict)) and "headers" in request:
|
|
210
|
+
context = extract_context_from_http_event_or_context(
|
|
211
|
+
request,
|
|
212
|
+
lambda_context,
|
|
213
|
+
event_source,
|
|
214
|
+
decode_authorizer_context=False,
|
|
215
|
+
)
|
|
216
|
+
else:
|
|
217
|
+
context = extract_context_from_lambda_context(lambda_context)
|
|
218
|
+
return context
|
|
219
|
+
|
|
220
|
+
|
|
212
221
|
def create_sns_event(message):
|
|
213
222
|
return {
|
|
214
223
|
"Records": [
|
|
@@ -627,6 +636,10 @@ def extract_dd_trace_context(
|
|
|
627
636
|
|
|
628
637
|
if extractor is not None:
|
|
629
638
|
context = extract_context_custom_extractor(extractor, event, lambda_context)
|
|
639
|
+
elif isinstance(event, (set, dict)) and "request" in event:
|
|
640
|
+
context = extract_context_from_request_header_or_context(
|
|
641
|
+
event, lambda_context, event_source
|
|
642
|
+
)
|
|
630
643
|
elif isinstance(event, (set, dict)) and "headers" in event:
|
|
631
644
|
context = extract_context_from_http_event_or_context(
|
|
632
645
|
event, lambda_context, event_source, decode_authorizer_context
|
|
@@ -325,7 +325,8 @@ def extract_http_tags(event):
|
|
|
325
325
|
method = apigateway_v2_http.get("method")
|
|
326
326
|
|
|
327
327
|
if path:
|
|
328
|
-
http_tags
|
|
328
|
+
if http_tags.get("http.url"):
|
|
329
|
+
http_tags["http.url"] += path
|
|
329
330
|
if method:
|
|
330
331
|
http_tags["http.method"] = method
|
|
331
332
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "8.118.0"
|
|
@@ -46,6 +46,10 @@ from datadog_lambda.trigger import (
|
|
|
46
46
|
extract_http_status_code_tag,
|
|
47
47
|
)
|
|
48
48
|
|
|
49
|
+
# ddtrace imports are also tested in
|
|
50
|
+
# dd-trace-py/tests/internal/test_serverless.py please update those tests when
|
|
51
|
+
# making changes to any ddtrace import.
|
|
52
|
+
|
|
49
53
|
if config.appsec_enabled:
|
|
50
54
|
from datadog_lambda.asm import (
|
|
51
55
|
asm_set_context,
|
|
@@ -65,7 +69,11 @@ if config.llmobs_enabled:
|
|
|
65
69
|
|
|
66
70
|
if config.exception_replay_enabled:
|
|
67
71
|
from ddtrace.debugging._exception.replay import SpanExceptionHandler
|
|
68
|
-
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
from ddtrace.debugging._uploader import SignalUploader
|
|
75
|
+
except ImportError:
|
|
76
|
+
from ddtrace.debugging._uploader import LogsIntakeUploaderV1 as SignalUploader
|
|
69
77
|
|
|
70
78
|
logger = logging.getLogger(__name__)
|
|
71
79
|
|
|
@@ -283,6 +291,10 @@ class _LambdaDecorator(object):
|
|
|
283
291
|
|
|
284
292
|
def _after(self, event, context):
|
|
285
293
|
try:
|
|
294
|
+
from datadog_lambda.metric import submit_batch_item_failures_metric
|
|
295
|
+
|
|
296
|
+
submit_batch_item_failures_metric(self.response, context)
|
|
297
|
+
|
|
286
298
|
status_code = extract_http_status_code_tag(self.trigger_tags, self.response)
|
|
287
299
|
|
|
288
300
|
if self.span:
|
|
@@ -370,7 +382,7 @@ class _LambdaDecorator(object):
|
|
|
370
382
|
|
|
371
383
|
# Flush exception replay
|
|
372
384
|
if config.exception_replay_enabled:
|
|
373
|
-
|
|
385
|
+
SignalUploader._instance.periodic()
|
|
374
386
|
|
|
375
387
|
if config.encode_authorizer_context and is_authorizer_response(
|
|
376
388
|
self.response
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "datadog_lambda"
|
|
3
|
-
version = "8.
|
|
3
|
+
version = "8.118.0"
|
|
4
4
|
description = "The Datadog AWS Lambda Library"
|
|
5
5
|
authors = ["Datadog, Inc. <dev@datadoghq.com>"]
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -22,13 +22,14 @@ classifiers = [
|
|
|
22
22
|
"Programming Language :: Python :: 3.11",
|
|
23
23
|
"Programming Language :: Python :: 3.12",
|
|
24
24
|
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Programming Language :: Python :: 3.14",
|
|
25
26
|
]
|
|
26
27
|
|
|
27
28
|
[tool.poetry.dependencies]
|
|
28
29
|
python = ">=3.8.0,<4"
|
|
29
30
|
datadog = ">=0.51.0,<1.0.0"
|
|
30
31
|
wrapt = "^1.11.2"
|
|
31
|
-
ddtrace = ">=3.
|
|
32
|
+
ddtrace = ">=3.16.2,<3.19.0"
|
|
32
33
|
ujson = ">=5.9.0"
|
|
33
34
|
botocore = { version = "^1.34.0", optional = true }
|
|
34
35
|
requests = { version ="^2.22.0", optional = true }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "8.114.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|