datadog_lambda 6.111.0__py3-none-any.whl → 7.112.0__py3-none-any.whl
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/__init__.py +7 -0
- datadog_lambda/asm.py +184 -0
- datadog_lambda/config.py +1 -0
- datadog_lambda/tracing.py +45 -7
- datadog_lambda/version.py +1 -1
- datadog_lambda/wrapper.py +18 -9
- {datadog_lambda-6.111.0.dist-info → datadog_lambda-7.112.0.dist-info}/METADATA +2 -2
- {datadog_lambda-6.111.0.dist-info → datadog_lambda-7.112.0.dist-info}/RECORD +12 -12
- datadog_lambda/dsm.py +0 -38
- {datadog_lambda-6.111.0.dist-info → datadog_lambda-7.112.0.dist-info}/LICENSE +0 -0
- {datadog_lambda-6.111.0.dist-info → datadog_lambda-7.112.0.dist-info}/LICENSE-3rdparty.csv +0 -0
- {datadog_lambda-6.111.0.dist-info → datadog_lambda-7.112.0.dist-info}/NOTICE +0 -0
- {datadog_lambda-6.111.0.dist-info → datadog_lambda-7.112.0.dist-info}/WHEEL +0 -0
datadog_lambda/__init__.py
CHANGED
|
@@ -17,3 +17,10 @@ from datadog_lambda.logger import initialize_logging # noqa: E402
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
initialize_logging(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
from datadog_lambda.patch import patch_all # noqa: E402
|
|
23
|
+
|
|
24
|
+
# Patch third-party libraries for tracing, must be done before importing any
|
|
25
|
+
# handler code.
|
|
26
|
+
patch_all()
|
datadog_lambda/asm.py
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
from copy import deepcopy
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Any, Dict, List, Optional, Union
|
|
4
|
+
|
|
5
|
+
from ddtrace.contrib.internal.trace_utils import _get_request_header_client_ip
|
|
6
|
+
from ddtrace.internal import core
|
|
7
|
+
from ddtrace.trace import Span
|
|
8
|
+
|
|
9
|
+
from datadog_lambda.trigger import (
|
|
10
|
+
EventSubtypes,
|
|
11
|
+
EventTypes,
|
|
12
|
+
_EventSource,
|
|
13
|
+
_http_event_types,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _to_single_value_headers(headers: Dict[str, List[str]]) -> Dict[str, str]:
|
|
20
|
+
"""
|
|
21
|
+
Convert multi-value headers to single-value headers.
|
|
22
|
+
If a header has multiple values, join them with commas.
|
|
23
|
+
"""
|
|
24
|
+
single_value_headers = {}
|
|
25
|
+
for key, values in headers.items():
|
|
26
|
+
single_value_headers[key] = ", ".join(values)
|
|
27
|
+
return single_value_headers
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _merge_single_and_multi_value_headers(
|
|
31
|
+
single_value_headers: Dict[str, str],
|
|
32
|
+
multi_value_headers: Dict[str, List[str]],
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
Merge single-value headers with multi-value headers.
|
|
36
|
+
If a header exists in both, we merge them removing duplicates
|
|
37
|
+
"""
|
|
38
|
+
merged_headers = deepcopy(multi_value_headers)
|
|
39
|
+
for key, value in single_value_headers.items():
|
|
40
|
+
if key not in merged_headers:
|
|
41
|
+
merged_headers[key] = [value]
|
|
42
|
+
elif value not in merged_headers[key]:
|
|
43
|
+
merged_headers[key].append(value)
|
|
44
|
+
return _to_single_value_headers(merged_headers)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def asm_set_context(event_source: _EventSource):
|
|
48
|
+
"""Add asm specific items to the ExecutionContext.
|
|
49
|
+
|
|
50
|
+
This allows the AppSecSpanProcessor to know information about the event
|
|
51
|
+
at the moment the span is created and skip it when not relevant.
|
|
52
|
+
"""
|
|
53
|
+
if event_source.event_type not in _http_event_types:
|
|
54
|
+
core.set_item("appsec_skip_next_lambda_event", True)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def asm_start_request(
|
|
58
|
+
span: Span,
|
|
59
|
+
event: Dict[str, Any],
|
|
60
|
+
event_source: _EventSource,
|
|
61
|
+
trigger_tags: Dict[str, str],
|
|
62
|
+
):
|
|
63
|
+
if event_source.event_type not in _http_event_types:
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
request_headers: Dict[str, str] = {}
|
|
67
|
+
peer_ip: Optional[str] = None
|
|
68
|
+
request_path_parameters: Optional[Dict[str, Any]] = None
|
|
69
|
+
route: Optional[str] = None
|
|
70
|
+
|
|
71
|
+
if event_source.event_type == EventTypes.ALB:
|
|
72
|
+
headers = event.get("headers")
|
|
73
|
+
multi_value_request_headers = event.get("multiValueHeaders")
|
|
74
|
+
if multi_value_request_headers:
|
|
75
|
+
request_headers = _to_single_value_headers(multi_value_request_headers)
|
|
76
|
+
else:
|
|
77
|
+
request_headers = headers or {}
|
|
78
|
+
|
|
79
|
+
raw_uri = event.get("path")
|
|
80
|
+
parsed_query = event.get("multiValueQueryStringParameters") or event.get(
|
|
81
|
+
"queryStringParameters"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
elif event_source.event_type == EventTypes.LAMBDA_FUNCTION_URL:
|
|
85
|
+
request_headers = event.get("headers", {})
|
|
86
|
+
peer_ip = event.get("requestContext", {}).get("http", {}).get("sourceIp")
|
|
87
|
+
raw_uri = event.get("rawPath")
|
|
88
|
+
parsed_query = event.get("queryStringParameters")
|
|
89
|
+
|
|
90
|
+
elif event_source.event_type == EventTypes.API_GATEWAY:
|
|
91
|
+
request_context = event.get("requestContext", {})
|
|
92
|
+
request_path_parameters = event.get("pathParameters")
|
|
93
|
+
route = trigger_tags.get("http.route")
|
|
94
|
+
|
|
95
|
+
if event_source.subtype == EventSubtypes.API_GATEWAY:
|
|
96
|
+
request_headers = event.get("headers", {})
|
|
97
|
+
peer_ip = request_context.get("identity", {}).get("sourceIp")
|
|
98
|
+
raw_uri = event.get("path")
|
|
99
|
+
parsed_query = event.get("multiValueQueryStringParameters")
|
|
100
|
+
|
|
101
|
+
elif event_source.subtype == EventSubtypes.HTTP_API:
|
|
102
|
+
request_headers = event.get("headers", {})
|
|
103
|
+
peer_ip = request_context.get("http", {}).get("sourceIp")
|
|
104
|
+
raw_uri = event.get("rawPath")
|
|
105
|
+
parsed_query = event.get("queryStringParameters")
|
|
106
|
+
|
|
107
|
+
elif event_source.subtype == EventSubtypes.WEBSOCKET:
|
|
108
|
+
request_headers = _to_single_value_headers(
|
|
109
|
+
event.get("multiValueHeaders", {})
|
|
110
|
+
)
|
|
111
|
+
peer_ip = request_context.get("identity", {}).get("sourceIp")
|
|
112
|
+
raw_uri = event.get("path")
|
|
113
|
+
parsed_query = event.get("multiValueQueryStringParameters")
|
|
114
|
+
|
|
115
|
+
else:
|
|
116
|
+
return
|
|
117
|
+
|
|
118
|
+
else:
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
body = event.get("body")
|
|
122
|
+
is_base64_encoded = event.get("isBase64Encoded", False)
|
|
123
|
+
|
|
124
|
+
request_ip = _get_request_header_client_ip(request_headers, peer_ip, True)
|
|
125
|
+
if request_ip is not None:
|
|
126
|
+
span.set_tag_str("http.client_ip", request_ip)
|
|
127
|
+
span.set_tag_str("network.client.ip", request_ip)
|
|
128
|
+
|
|
129
|
+
core.dispatch(
|
|
130
|
+
# The matching listener is registered in ddtrace.appsec._handlers
|
|
131
|
+
"aws_lambda.start_request",
|
|
132
|
+
(
|
|
133
|
+
span,
|
|
134
|
+
request_headers,
|
|
135
|
+
request_ip,
|
|
136
|
+
body,
|
|
137
|
+
is_base64_encoded,
|
|
138
|
+
raw_uri,
|
|
139
|
+
route,
|
|
140
|
+
trigger_tags.get("http.method"),
|
|
141
|
+
parsed_query,
|
|
142
|
+
request_path_parameters,
|
|
143
|
+
),
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def asm_start_response(
|
|
148
|
+
span: Span,
|
|
149
|
+
status_code: str,
|
|
150
|
+
event_source: _EventSource,
|
|
151
|
+
response: Union[Dict[str, Any], str, None],
|
|
152
|
+
):
|
|
153
|
+
if event_source.event_type not in _http_event_types:
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
if isinstance(response, dict) and (
|
|
157
|
+
"headers" in response or "multiValueHeaders" in response
|
|
158
|
+
):
|
|
159
|
+
headers = response.get("headers", {})
|
|
160
|
+
multi_value_request_headers = response.get("multiValueHeaders")
|
|
161
|
+
if isinstance(multi_value_request_headers, dict) and isinstance(headers, dict):
|
|
162
|
+
response_headers = _merge_single_and_multi_value_headers(
|
|
163
|
+
headers, multi_value_request_headers
|
|
164
|
+
)
|
|
165
|
+
elif isinstance(headers, dict):
|
|
166
|
+
response_headers = headers
|
|
167
|
+
else:
|
|
168
|
+
response_headers = {
|
|
169
|
+
"content-type": "application/json",
|
|
170
|
+
}
|
|
171
|
+
else:
|
|
172
|
+
response_headers = {
|
|
173
|
+
"content-type": "application/json",
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
core.dispatch(
|
|
177
|
+
# The matching listener is registered in ddtrace.appsec._handlers
|
|
178
|
+
"aws_lambda.start_response",
|
|
179
|
+
(
|
|
180
|
+
span,
|
|
181
|
+
status_code,
|
|
182
|
+
response_headers,
|
|
183
|
+
),
|
|
184
|
+
)
|
datadog_lambda/config.py
CHANGED
|
@@ -95,6 +95,7 @@ class Config:
|
|
|
95
95
|
data_streams_enabled = _get_env(
|
|
96
96
|
"DD_DATA_STREAMS_ENABLED", "false", as_bool, depends_on_tracing=True
|
|
97
97
|
)
|
|
98
|
+
appsec_enabled = _get_env("DD_APPSEC_ENABLED", "false", as_bool)
|
|
98
99
|
|
|
99
100
|
is_gov_region = _get_env("AWS_REGION", "", lambda x: x.startswith("us-gov-"))
|
|
100
101
|
|
datadog_lambda/tracing.py
CHANGED
|
@@ -67,6 +67,24 @@ HIGHER_64_BITS = "HIGHER_64_BITS"
|
|
|
67
67
|
LOWER_64_BITS = "LOWER_64_BITS"
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
def _dsm_set_checkpoint(context_json, event_type, arn):
|
|
71
|
+
if not config.data_streams_enabled:
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
if not arn:
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
from ddtrace.data_streams import set_consume_checkpoint
|
|
79
|
+
|
|
80
|
+
carrier_get = lambda k: context_json and context_json.get(k) # noqa: E731
|
|
81
|
+
set_consume_checkpoint(event_type, arn, carrier_get, manual_checkpoint=False)
|
|
82
|
+
except Exception as e:
|
|
83
|
+
logger.debug(
|
|
84
|
+
f"DSM:Failed to set consume checkpoint for {event_type} {arn}: {e}"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
70
88
|
def _convert_xray_trace_id(xray_trace_id):
|
|
71
89
|
"""
|
|
72
90
|
Convert X-Ray trace id (hex)'s last 63 bits to a Datadog trace id (int).
|
|
@@ -202,7 +220,9 @@ def create_sns_event(message):
|
|
|
202
220
|
}
|
|
203
221
|
|
|
204
222
|
|
|
205
|
-
def extract_context_from_sqs_or_sns_event_or_context(
|
|
223
|
+
def extract_context_from_sqs_or_sns_event_or_context(
|
|
224
|
+
event, lambda_context, event_source
|
|
225
|
+
):
|
|
206
226
|
"""
|
|
207
227
|
Extract Datadog trace context from an SQS event.
|
|
208
228
|
|
|
@@ -214,7 +234,10 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context):
|
|
|
214
234
|
Lambda Context.
|
|
215
235
|
|
|
216
236
|
Falls back to lambda context if no trace data is found in the SQS message attributes.
|
|
237
|
+
Set a DSM checkpoint if DSM is enabled and the method for context propagation is supported.
|
|
217
238
|
"""
|
|
239
|
+
source_arn = ""
|
|
240
|
+
event_type = "sqs" if event_source.equals(EventTypes.SQS) else "sns"
|
|
218
241
|
|
|
219
242
|
# EventBridge => SQS
|
|
220
243
|
try:
|
|
@@ -226,6 +249,7 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context):
|
|
|
226
249
|
|
|
227
250
|
try:
|
|
228
251
|
first_record = event.get("Records")[0]
|
|
252
|
+
source_arn = first_record.get("eventSourceARN", "")
|
|
229
253
|
|
|
230
254
|
# logic to deal with SNS => SQS event
|
|
231
255
|
if "body" in first_record:
|
|
@@ -241,6 +265,9 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context):
|
|
|
241
265
|
msg_attributes = first_record.get("messageAttributes")
|
|
242
266
|
if msg_attributes is None:
|
|
243
267
|
sns_record = first_record.get("Sns") or {}
|
|
268
|
+
# SNS->SQS event would extract SNS arn without this check
|
|
269
|
+
if event_source.equals(EventTypes.SNS):
|
|
270
|
+
source_arn = sns_record.get("TopicArn", "")
|
|
244
271
|
msg_attributes = sns_record.get("MessageAttributes") or {}
|
|
245
272
|
dd_payload = msg_attributes.get("_datadog")
|
|
246
273
|
if dd_payload:
|
|
@@ -272,8 +299,9 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context):
|
|
|
272
299
|
logger.debug(
|
|
273
300
|
"Failed to extract Step Functions context from SQS/SNS event."
|
|
274
301
|
)
|
|
275
|
-
|
|
276
|
-
|
|
302
|
+
context = propagator.extract(dd_data)
|
|
303
|
+
_dsm_set_checkpoint(dd_data, event_type, source_arn)
|
|
304
|
+
return context
|
|
277
305
|
else:
|
|
278
306
|
# Handle case where trace context is injected into attributes.AWSTraceHeader
|
|
279
307
|
# example: Root=1-654321ab-000000001234567890abcdef;Parent=0123456789abcdef;Sampled=1
|
|
@@ -296,9 +324,13 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context):
|
|
|
296
324
|
span_id=int(x_ray_context["parent_id"], 16),
|
|
297
325
|
sampling_priority=float(x_ray_context["sampled"]),
|
|
298
326
|
)
|
|
327
|
+
# Still want to set a DSM checkpoint even if DSM context not propagated
|
|
328
|
+
_dsm_set_checkpoint(None, event_type, source_arn)
|
|
299
329
|
return extract_context_from_lambda_context(lambda_context)
|
|
300
330
|
except Exception as e:
|
|
301
331
|
logger.debug("The trace extractor returned with error %s", e)
|
|
332
|
+
# Still want to set a DSM checkpoint even if DSM context not propagated
|
|
333
|
+
_dsm_set_checkpoint(None, event_type, source_arn)
|
|
302
334
|
return extract_context_from_lambda_context(lambda_context)
|
|
303
335
|
|
|
304
336
|
|
|
@@ -357,9 +389,12 @@ def extract_context_from_eventbridge_event(event, lambda_context):
|
|
|
357
389
|
def extract_context_from_kinesis_event(event, lambda_context):
|
|
358
390
|
"""
|
|
359
391
|
Extract datadog trace context from a Kinesis Stream's base64 encoded data string
|
|
392
|
+
Set a DSM checkpoint if DSM is enabled and the method for context propagation is supported.
|
|
360
393
|
"""
|
|
394
|
+
source_arn = ""
|
|
361
395
|
try:
|
|
362
396
|
record = get_first_record(event)
|
|
397
|
+
source_arn = record.get("eventSourceARN", "")
|
|
363
398
|
kinesis = record.get("kinesis")
|
|
364
399
|
if not kinesis:
|
|
365
400
|
return extract_context_from_lambda_context(lambda_context)
|
|
@@ -373,10 +408,13 @@ def extract_context_from_kinesis_event(event, lambda_context):
|
|
|
373
408
|
data_obj = json.loads(data_str)
|
|
374
409
|
dd_ctx = data_obj.get("_datadog")
|
|
375
410
|
if dd_ctx:
|
|
376
|
-
|
|
411
|
+
context = propagator.extract(dd_ctx)
|
|
412
|
+
_dsm_set_checkpoint(dd_ctx, "kinesis", source_arn)
|
|
413
|
+
return context
|
|
377
414
|
except Exception as e:
|
|
378
415
|
logger.debug("The trace extractor returned with error %s", e)
|
|
379
|
-
|
|
416
|
+
# Still want to set a DSM checkpoint even if DSM context not propagated
|
|
417
|
+
_dsm_set_checkpoint(None, "kinesis", source_arn)
|
|
380
418
|
return extract_context_from_lambda_context(lambda_context)
|
|
381
419
|
|
|
382
420
|
|
|
@@ -594,7 +632,7 @@ def extract_dd_trace_context(
|
|
|
594
632
|
)
|
|
595
633
|
elif event_source.equals(EventTypes.SNS) or event_source.equals(EventTypes.SQS):
|
|
596
634
|
context = extract_context_from_sqs_or_sns_event_or_context(
|
|
597
|
-
event, lambda_context
|
|
635
|
+
event, lambda_context, event_source
|
|
598
636
|
)
|
|
599
637
|
elif event_source.equals(EventTypes.EVENTBRIDGE):
|
|
600
638
|
context = extract_context_from_eventbridge_event(event, lambda_context)
|
|
@@ -859,7 +897,7 @@ def create_inferred_span_from_lambda_function_url_event(event, context):
|
|
|
859
897
|
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync")
|
|
860
898
|
if span:
|
|
861
899
|
span.set_tags(tags)
|
|
862
|
-
span.start_ns = int(request_time_epoch
|
|
900
|
+
span.start_ns = int(request_time_epoch * 1e6)
|
|
863
901
|
return span
|
|
864
902
|
|
|
865
903
|
|
datadog_lambda/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "
|
|
1
|
+
__version__ = "7.112.0"
|
datadog_lambda/wrapper.py
CHANGED
|
@@ -9,7 +9,7 @@ import ujson as json
|
|
|
9
9
|
from importlib import import_module
|
|
10
10
|
from time import time_ns
|
|
11
11
|
|
|
12
|
-
from datadog_lambda.
|
|
12
|
+
from datadog_lambda.asm import asm_set_context, asm_start_response, asm_start_request
|
|
13
13
|
from datadog_lambda.extension import should_use_extension, flush_extension
|
|
14
14
|
from datadog_lambda.cold_start import (
|
|
15
15
|
set_cold_start,
|
|
@@ -25,7 +25,6 @@ from datadog_lambda.constants import (
|
|
|
25
25
|
Headers,
|
|
26
26
|
)
|
|
27
27
|
from datadog_lambda.module_name import modify_module_name
|
|
28
|
-
from datadog_lambda.patch import patch_all
|
|
29
28
|
from datadog_lambda.span_pointers import calculate_span_pointers
|
|
30
29
|
from datadog_lambda.tag_object import tag_object
|
|
31
30
|
from datadog_lambda.tracing import (
|
|
@@ -142,8 +141,6 @@ class _LambdaDecorator(object):
|
|
|
142
141
|
os.environ[DD_REQUESTS_SERVICE_NAME] = os.environ.get(
|
|
143
142
|
DD_SERVICE, "aws.lambda"
|
|
144
143
|
)
|
|
145
|
-
# Patch third-party libraries for tracing
|
|
146
|
-
patch_all()
|
|
147
144
|
|
|
148
145
|
# Enable LLM Observability
|
|
149
146
|
if config.llmobs_enabled:
|
|
@@ -165,10 +162,9 @@ class _LambdaDecorator(object):
|
|
|
165
162
|
self.response = self.func(event, context, **kwargs)
|
|
166
163
|
return self.response
|
|
167
164
|
except Exception:
|
|
168
|
-
|
|
169
|
-
from datadog_lambda.metric import submit_errors_metric
|
|
165
|
+
from datadog_lambda.metric import submit_errors_metric
|
|
170
166
|
|
|
171
|
-
|
|
167
|
+
submit_errors_metric(context)
|
|
172
168
|
|
|
173
169
|
if self.span:
|
|
174
170
|
self.span.set_traceback()
|
|
@@ -240,8 +236,10 @@ class _LambdaDecorator(object):
|
|
|
240
236
|
self.inferred_span = create_inferred_span(
|
|
241
237
|
event, context, event_source, config.decode_authorizer_context
|
|
242
238
|
)
|
|
243
|
-
|
|
244
|
-
|
|
239
|
+
|
|
240
|
+
if config.appsec_enabled:
|
|
241
|
+
asm_set_context(event_source)
|
|
242
|
+
|
|
245
243
|
self.span = create_function_execution_span(
|
|
246
244
|
context=context,
|
|
247
245
|
function_name=config.function_name,
|
|
@@ -253,6 +251,8 @@ class _LambdaDecorator(object):
|
|
|
253
251
|
parent_span=self.inferred_span,
|
|
254
252
|
span_pointers=calculate_span_pointers(event_source, event),
|
|
255
253
|
)
|
|
254
|
+
if config.appsec_enabled:
|
|
255
|
+
asm_start_request(self.span, event, event_source, self.trigger_tags)
|
|
256
256
|
else:
|
|
257
257
|
set_correlation_ids()
|
|
258
258
|
if config.profiling_enabled and is_new_sandbox():
|
|
@@ -285,6 +285,15 @@ class _LambdaDecorator(object):
|
|
|
285
285
|
|
|
286
286
|
if status_code:
|
|
287
287
|
self.span.set_tag("http.status_code", status_code)
|
|
288
|
+
|
|
289
|
+
if config.appsec_enabled:
|
|
290
|
+
asm_start_response(
|
|
291
|
+
self.span,
|
|
292
|
+
status_code,
|
|
293
|
+
self.event_source,
|
|
294
|
+
response=self.response,
|
|
295
|
+
)
|
|
296
|
+
|
|
288
297
|
self.span.finish()
|
|
289
298
|
|
|
290
299
|
if self.inferred_span:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: datadog_lambda
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.112.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
|
|
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Provides-Extra: dev
|
|
20
20
|
Requires-Dist: botocore (>=1.34.0,<2.0.0) ; extra == "dev"
|
|
21
21
|
Requires-Dist: datadog (>=0.51.0,<1.0.0)
|
|
22
|
-
Requires-Dist: ddtrace (>=
|
|
22
|
+
Requires-Dist: ddtrace (>=3.10.2,<4)
|
|
23
23
|
Requires-Dist: flake8 (>=5.0.4,<6.0.0) ; extra == "dev"
|
|
24
24
|
Requires-Dist: pytest (>=8.0.0,<9.0.0) ; extra == "dev"
|
|
25
25
|
Requires-Dist: pytest-benchmark (>=4.0,<5.0) ; extra == "dev"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
datadog_lambda/__init__.py,sha256=
|
|
1
|
+
datadog_lambda/__init__.py,sha256=uAqki08Fd26eUXZtoptJX68kTFhK-ZkCyLVCtE0MS4k,802
|
|
2
2
|
datadog_lambda/api.py,sha256=FqQ9vjNSxD5BxjeHDDKbim_NIN08dshW-52wNzqw5yo,5249
|
|
3
|
+
datadog_lambda/asm.py,sha256=gX4ySlmLCGnOWRf0LpMJxDElpQ2su5LnphJJy4Lrc-Y,6115
|
|
3
4
|
datadog_lambda/cold_start.py,sha256=NfE4EtRUHuc2ub26U8sAwMVEDNINbw1OTh2MAklQGyk,8032
|
|
4
|
-
datadog_lambda/config.py,sha256=
|
|
5
|
+
datadog_lambda/config.py,sha256=QoEZrSL_zSHY5lV9RznAwPONEZe0i3mCWp2jPoO8aEw,5260
|
|
5
6
|
datadog_lambda/constants.py,sha256=0y6O9s_8RLflYR507SDMQjKmYY16tr1yi2KQuuF1GaY,1696
|
|
6
7
|
datadog_lambda/dogstatsd.py,sha256=-2HiU3xvV_beXh8rI9oIXxSUmVcamI0KqAl7gc9LkYA,5216
|
|
7
|
-
datadog_lambda/dsm.py,sha256=TwRGl7bpWMpkv1YJtRsjsCma4QTI3xKrpOvj2GmMO_A,1219
|
|
8
8
|
datadog_lambda/extension.py,sha256=ZU64QpA2K9K9C0jfqusBgpiWQe0QA2dcJCNk7UgjVfw,621
|
|
9
9
|
datadog_lambda/handler.py,sha256=VhdNUb_lpPRJ73h-fdDxxqSm0Ic_lkt4x_9Rt0amVV4,1312
|
|
10
10
|
datadog_lambda/logger.py,sha256=nGxNMouF7wcjmoPsgivzzjNLvSy3WbGtKElxOvITZDg,766
|
|
@@ -17,14 +17,14 @@ datadog_lambda/statsd_writer.py,sha256=wUNG8phIreNOGCc5VjYZV-FNogvKfiz9kN33QldqZ
|
|
|
17
17
|
datadog_lambda/tag_object.py,sha256=NNvMVi07kNYRBMPpB7Lk7_-z5ccmxo2UmTWnvWVPhiM,2089
|
|
18
18
|
datadog_lambda/tags.py,sha256=wy6uH8eAGMn7cfZEdHpL9uEGoM85bVyyXhYwSQtfHHc,2532
|
|
19
19
|
datadog_lambda/thread_stats_writer.py,sha256=VfD6G65zNHDA0nABhGOO0it7yqvn-p6ereQ329DA7r8,2894
|
|
20
|
-
datadog_lambda/tracing.py,sha256=
|
|
20
|
+
datadog_lambda/tracing.py,sha256=aalT3t_ISPvPZIZzkrSK6OnW1ixY9ijsefjUQQEKQk0,56071
|
|
21
21
|
datadog_lambda/trigger.py,sha256=7EhNoCtJbnuYaqCvv1i2tAqZxfXx7ccsnMkwnWvmd7w,14212
|
|
22
|
-
datadog_lambda/version.py,sha256=
|
|
23
|
-
datadog_lambda/wrapper.py,sha256=
|
|
22
|
+
datadog_lambda/version.py,sha256=HDtiDcfxQBWPKo0xjxP1Hvuj0QipaSpVwhvqFrmieB0,24
|
|
23
|
+
datadog_lambda/wrapper.py,sha256=siHNfNSLb3iIwN0vRnW67CtnOirqogbFG54zjWPVLAU,13377
|
|
24
24
|
datadog_lambda/xray.py,sha256=jvA4Fk76PLMgsjUoUZ7gp2otv53hFt39Nvso1ZNaivg,3749
|
|
25
|
-
datadog_lambda-
|
|
26
|
-
datadog_lambda-
|
|
27
|
-
datadog_lambda-
|
|
28
|
-
datadog_lambda-
|
|
29
|
-
datadog_lambda-
|
|
30
|
-
datadog_lambda-
|
|
25
|
+
datadog_lambda-7.112.0.dist-info/LICENSE,sha256=4yQmjpKp1MKL7DdRDPVHkKYc2W0aezm5SIDske8oAdM,11379
|
|
26
|
+
datadog_lambda-7.112.0.dist-info/LICENSE-3rdparty.csv,sha256=9CDAR1GKawwTbZkqt1RP0uwEcaRM3RhOeTB5tWXr8Ts,1381
|
|
27
|
+
datadog_lambda-7.112.0.dist-info/METADATA,sha256=YzLOAslZUkBtDAPKfgPyYnpbXKUwd92D1zZbctuFBR4,7727
|
|
28
|
+
datadog_lambda-7.112.0.dist-info/NOTICE,sha256=Jue-d8mQ1ENIHDZdYc2-X8mVYtScXb8pzF1pTLN-kRc,141
|
|
29
|
+
datadog_lambda-7.112.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
30
|
+
datadog_lambda-7.112.0.dist-info/RECORD,,
|
datadog_lambda/dsm.py
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
from datadog_lambda import logger
|
|
2
|
-
from datadog_lambda.trigger import EventTypes
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def set_dsm_context(event, event_source):
|
|
6
|
-
|
|
7
|
-
if event_source.equals(EventTypes.SQS):
|
|
8
|
-
_dsm_set_sqs_context(event)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def _dsm_set_sqs_context(event):
|
|
12
|
-
from datadog_lambda.wrapper import format_err_with_traceback
|
|
13
|
-
from ddtrace.internal.datastreams import data_streams_processor
|
|
14
|
-
from ddtrace.internal.datastreams.processor import DsmPathwayCodec
|
|
15
|
-
from ddtrace.internal.datastreams.botocore import (
|
|
16
|
-
get_datastreams_context,
|
|
17
|
-
calculate_sqs_payload_size,
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
records = event.get("Records")
|
|
21
|
-
if records is None:
|
|
22
|
-
return
|
|
23
|
-
processor = data_streams_processor()
|
|
24
|
-
|
|
25
|
-
for record in records:
|
|
26
|
-
try:
|
|
27
|
-
queue_arn = record.get("eventSourceARN", "")
|
|
28
|
-
|
|
29
|
-
contextjson = get_datastreams_context(record)
|
|
30
|
-
payload_size = calculate_sqs_payload_size(record)
|
|
31
|
-
|
|
32
|
-
ctx = DsmPathwayCodec.decode(contextjson, processor)
|
|
33
|
-
ctx.set_checkpoint(
|
|
34
|
-
["direction:in", f"topic:{queue_arn}", "type:sqs"],
|
|
35
|
-
payload_size=payload_size,
|
|
36
|
-
)
|
|
37
|
-
except Exception as e:
|
|
38
|
-
logger.error(format_err_with_traceback(e))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|