datadog_lambda 5.94.0__tar.gz → 6.96.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-5.94.0 → datadog_lambda-6.96.0}/PKG-INFO +5 -2
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/README.md +3 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/api.py +2 -6
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/cold_start.py +2 -1
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/metric.py +23 -3
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/tracing.py +34 -16
- datadog_lambda-6.96.0/datadog_lambda/version.py +1 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/pyproject.toml +2 -2
- datadog_lambda-5.94.0/datadog_lambda/version.py +0 -1
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/LICENSE +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/LICENSE-3rdparty.csv +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/NOTICE +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/__init__.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/constants.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/dogstatsd.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/extension.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/handler.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/logger.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/module_name.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/patch.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/stats_writer.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/statsd_writer.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/tag_object.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/tags.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/thread_stats_writer.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/trigger.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/wrapper.py +0 -0
- {datadog_lambda-5.94.0 → datadog_lambda-6.96.0}/datadog_lambda/xray.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: datadog_lambda
|
|
3
|
-
Version:
|
|
3
|
+
Version: 6.96.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
|
|
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
18
|
Provides-Extra: dev
|
|
19
19
|
Requires-Dist: boto3 (>=1.28.0,<2.0.0) ; extra == "dev"
|
|
20
20
|
Requires-Dist: datadog (>=0.41.0,<1.0.0)
|
|
21
|
-
Requires-Dist: ddtrace (>=2.
|
|
21
|
+
Requires-Dist: ddtrace (>=2.9.0)
|
|
22
22
|
Requires-Dist: flake8 (>=5.0.4,<6.0.0) ; extra == "dev"
|
|
23
23
|
Requires-Dist: pytest (>=8.0.0,<9.0.0) ; extra == "dev"
|
|
24
24
|
Requires-Dist: pytest-benchmark (>=4.0,<5.0) ; extra == "dev"
|
|
@@ -79,6 +79,9 @@ The Continuous Profiler works by spawning a thread which periodically wakes up a
|
|
|
79
79
|
|
|
80
80
|
## Major Version Notes
|
|
81
81
|
|
|
82
|
+
### 6.x / Layer version 95+
|
|
83
|
+
- The release changed how Lambda's traceID is hashed if the incoming payload contains Step Functions context object. This change only affects those who uses inject Step Functions context object into Lambda payload.
|
|
84
|
+
|
|
82
85
|
### 5.x / Layer version 86+
|
|
83
86
|
- Python3.7 support has been [deprecated](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) by AWS, and support removed from this library.
|
|
84
87
|
|
|
@@ -47,6 +47,9 @@ The Continuous Profiler works by spawning a thread which periodically wakes up a
|
|
|
47
47
|
|
|
48
48
|
## Major Version Notes
|
|
49
49
|
|
|
50
|
+
### 6.x / Layer version 95+
|
|
51
|
+
- The release changed how Lambda's traceID is hashed if the incoming payload contains Step Functions context object. This change only affects those who uses inject Step Functions context object into Lambda payload.
|
|
52
|
+
|
|
50
53
|
### 5.x / Layer version 86+
|
|
51
54
|
- Python3.7 support has been [deprecated](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) by AWS, and support removed from this library.
|
|
52
55
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import logging
|
|
3
3
|
import base64
|
|
4
|
-
from datadog_lambda.extension import should_use_extension
|
|
5
4
|
|
|
6
5
|
logger = logging.getLogger(__name__)
|
|
7
6
|
KMS_ENCRYPTION_CONTEXT_KEY = "LambdaFunctionName"
|
|
@@ -48,13 +47,10 @@ def decrypt_kms_api_key(kms_client, ciphertext):
|
|
|
48
47
|
|
|
49
48
|
|
|
50
49
|
def init_api():
|
|
51
|
-
if (
|
|
52
|
-
not should_use_extension
|
|
53
|
-
and not os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true"
|
|
54
|
-
):
|
|
50
|
+
if not os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true":
|
|
55
51
|
# Make sure that this package would always be lazy-loaded/outside from the critical path
|
|
56
52
|
# since underlying packages are quite heavy to load
|
|
57
|
-
# and useless
|
|
53
|
+
# and useless with the extension unless sending metrics with timestamps
|
|
58
54
|
from datadog import api
|
|
59
55
|
|
|
60
56
|
if not api._api_key:
|
|
@@ -197,7 +197,8 @@ class ColdStartTracer(object):
|
|
|
197
197
|
|
|
198
198
|
def trace_tree(self, import_node: ImportNode, parent_span):
|
|
199
199
|
if (
|
|
200
|
-
|
|
200
|
+
not self.trace_ctx
|
|
201
|
+
or import_node.end_time_ns - import_node.start_time_ns
|
|
201
202
|
< self.min_duration_ms * 1e6
|
|
202
203
|
or import_node.module_name in self.ignored_libs
|
|
203
204
|
):
|
|
@@ -10,13 +10,13 @@ import ujson as json
|
|
|
10
10
|
|
|
11
11
|
from datadog_lambda.extension import should_use_extension
|
|
12
12
|
from datadog_lambda.tags import get_enhanced_metrics_tags, dd_lambda_layer_tag
|
|
13
|
-
from datadog_lambda.api import init_api
|
|
14
13
|
|
|
15
14
|
logger = logging.getLogger(__name__)
|
|
16
15
|
|
|
17
16
|
lambda_stats = None
|
|
17
|
+
extension_thread_stats = None
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
flush_in_thread = os.environ.get("DD_FLUSH_IN_THREAD", "").lower() == "true"
|
|
20
20
|
|
|
21
21
|
if should_use_extension:
|
|
22
22
|
from datadog_lambda.statsd_writer import StatsDWriter
|
|
@@ -28,8 +28,9 @@ else:
|
|
|
28
28
|
# end of invocation. To make metrics submitted from a long-running Lambda
|
|
29
29
|
# function available sooner, consider using the Datadog Lambda extension.
|
|
30
30
|
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
|
|
31
|
+
from datadog_lambda.api import init_api
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
init_api()
|
|
33
34
|
lambda_stats = ThreadStatsWriter(flush_in_thread)
|
|
34
35
|
|
|
35
36
|
enhanced_metrics_enabled = (
|
|
@@ -57,6 +58,22 @@ def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=Fal
|
|
|
57
58
|
tags = [] if tags is None else list(tags)
|
|
58
59
|
tags.append(dd_lambda_layer_tag)
|
|
59
60
|
|
|
61
|
+
if should_use_extension and timestamp is not None:
|
|
62
|
+
# The extension does not support timestamps for distributions so we create a
|
|
63
|
+
# a thread stats writer to submit metrics with timestamps to the API
|
|
64
|
+
global extension_thread_stats
|
|
65
|
+
if extension_thread_stats is None:
|
|
66
|
+
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
|
|
67
|
+
from datadog_lambda.api import init_api
|
|
68
|
+
|
|
69
|
+
init_api()
|
|
70
|
+
extension_thread_stats = ThreadStatsWriter(flush_in_thread)
|
|
71
|
+
|
|
72
|
+
extension_thread_stats.distribution(
|
|
73
|
+
metric_name, value, tags=tags, timestamp=timestamp
|
|
74
|
+
)
|
|
75
|
+
return
|
|
76
|
+
|
|
60
77
|
if should_use_extension:
|
|
61
78
|
logger.debug(
|
|
62
79
|
"Sending metric %s value %s to Datadog via extension", metric_name, value
|
|
@@ -94,6 +111,9 @@ def write_metric_point_to_stdout(metric_name, value, timestamp=None, tags=[]):
|
|
|
94
111
|
def flush_stats():
|
|
95
112
|
lambda_stats.flush()
|
|
96
113
|
|
|
114
|
+
if extension_thread_stats is not None:
|
|
115
|
+
extension_thread_stats.flush()
|
|
116
|
+
|
|
97
117
|
|
|
98
118
|
def submit_enhanced_metric(metric_name, lambda_context):
|
|
99
119
|
"""Submits the enhanced metric with the given name
|
|
@@ -72,6 +72,8 @@ is_lambda_context = os.environ.get(XrayDaemon.FUNCTION_NAME_HEADER_NAME) != ""
|
|
|
72
72
|
propagator = HTTPPropagator()
|
|
73
73
|
|
|
74
74
|
DD_TRACE_JAVA_TRACE_ID_PADDING = "00000000"
|
|
75
|
+
HIGHER_64_BITS = "HIGHER_64_BITS"
|
|
76
|
+
LOWER_64_BITS = "LOWER_64_BITS"
|
|
75
77
|
|
|
76
78
|
|
|
77
79
|
def _convert_xray_trace_id(xray_trace_id):
|
|
@@ -273,7 +275,7 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context):
|
|
|
273
275
|
else:
|
|
274
276
|
# Handle case where trace context is injected into attributes.AWSTraceHeader
|
|
275
277
|
# example: Root=1-654321ab-000000001234567890abcdef;Parent=0123456789abcdef;Sampled=1
|
|
276
|
-
attrs =
|
|
278
|
+
attrs = event.get("Records")[0].get("attributes")
|
|
277
279
|
if attrs:
|
|
278
280
|
x_ray_header = attrs.get("AWSTraceHeader")
|
|
279
281
|
if x_ray_header:
|
|
@@ -354,14 +356,16 @@ def extract_context_from_kinesis_event(event, lambda_context):
|
|
|
354
356
|
return extract_context_from_lambda_context(lambda_context)
|
|
355
357
|
|
|
356
358
|
|
|
357
|
-
def
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
359
|
+
def _deterministic_sha256_hash(s: str, part: str) -> (int, int):
|
|
360
|
+
sha256_hash = hashlib.sha256(s.encode()).hexdigest()
|
|
361
|
+
|
|
362
|
+
# First two chars is '0b'. zfill to ensure 256 bits, but we only care about the first 128 bits
|
|
363
|
+
binary_hash = bin(int(sha256_hash, 16))[2:].zfill(256)
|
|
364
|
+
if part == HIGHER_64_BITS:
|
|
365
|
+
updated_binary_hash = "0" + binary_hash[1:64]
|
|
366
|
+
else:
|
|
367
|
+
updated_binary_hash = "0" + binary_hash[65:128]
|
|
368
|
+
result = int(updated_binary_hash, 2)
|
|
365
369
|
if result == 0:
|
|
366
370
|
return 1
|
|
367
371
|
return result
|
|
@@ -376,13 +380,27 @@ def extract_context_from_step_functions(event, lambda_context):
|
|
|
376
380
|
execution_id = event.get("Execution").get("Id")
|
|
377
381
|
state_name = event.get("State").get("Name")
|
|
378
382
|
state_entered_time = event.get("State").get("EnteredTime")
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
383
|
+
# returning 128 bits since 128bit traceId will be break up into
|
|
384
|
+
# traditional traceId and _dd.p.tid tag
|
|
385
|
+
# https://github.com/DataDog/dd-trace-py/blob/3e34d21cb9b5e1916e549047158cb119317b96ab/ddtrace/propagation/http.py#L232-L240
|
|
386
|
+
trace_id = _deterministic_sha256_hash(execution_id, LOWER_64_BITS)
|
|
387
|
+
|
|
388
|
+
parent_id = _deterministic_sha256_hash(
|
|
389
|
+
f"{execution_id}#{state_name}#{state_entered_time}", HIGHER_64_BITS
|
|
382
390
|
)
|
|
391
|
+
|
|
383
392
|
sampling_priority = SamplingPriority.AUTO_KEEP
|
|
384
393
|
return Context(
|
|
385
|
-
trace_id=trace_id,
|
|
394
|
+
trace_id=trace_id,
|
|
395
|
+
span_id=parent_id,
|
|
396
|
+
sampling_priority=sampling_priority,
|
|
397
|
+
# take the higher 64 bits as _dd.p.tid tag and use hex to encode
|
|
398
|
+
# [2:] to remove '0x' in the hex str
|
|
399
|
+
meta={
|
|
400
|
+
"_dd.p.tid": hex(
|
|
401
|
+
_deterministic_sha256_hash(execution_id, HIGHER_64_BITS)
|
|
402
|
+
)[2:]
|
|
403
|
+
},
|
|
386
404
|
)
|
|
387
405
|
except Exception as e:
|
|
388
406
|
logger.debug("The Step Functions trace extractor returned with error %s", e)
|
|
@@ -1246,9 +1264,9 @@ def create_function_execution_span(
|
|
|
1246
1264
|
"function_version": function_version,
|
|
1247
1265
|
"request_id": context.aws_request_id,
|
|
1248
1266
|
"resource_names": context.function_name,
|
|
1249
|
-
"functionname":
|
|
1250
|
-
|
|
1251
|
-
|
|
1267
|
+
"functionname": (
|
|
1268
|
+
context.function_name.lower() if context.function_name else None
|
|
1269
|
+
),
|
|
1252
1270
|
"datadog_lambda": datadog_lambda_version,
|
|
1253
1271
|
"dd_trace": ddtrace_version,
|
|
1254
1272
|
"span.name": "aws.lambda",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "6.96.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "datadog_lambda"
|
|
3
|
-
version = "
|
|
3
|
+
version = "6.96.0"
|
|
4
4
|
description = "The Datadog AWS Lambda Library"
|
|
5
5
|
authors = ["Datadog, Inc. <dev@datadoghq.com>"]
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -27,7 +27,7 @@ classifiers = [
|
|
|
27
27
|
python = ">=3.8.0,<4"
|
|
28
28
|
datadog = ">=0.41.0,<1.0.0"
|
|
29
29
|
wrapt = "^1.11.2"
|
|
30
|
-
ddtrace = ">=2.
|
|
30
|
+
ddtrace = ">=2.9.0"
|
|
31
31
|
ujson = ">=5.9.0"
|
|
32
32
|
urllib3 = [
|
|
33
33
|
{version = "<2.0.0", python = "<3.11", optional = true},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "5.94.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
|
|
File without changes
|