datadog_lambda 8.123.0__tar.gz → 8.125.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.
Files changed (32) hide show
  1. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/PKG-INFO +11 -6
  2. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/config.py +11 -0
  3. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/durable.py +23 -3
  4. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/tracing.py +7 -10
  5. datadog_lambda-8.125.0/datadog_lambda/version.py +1 -0
  6. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/wrapper.py +25 -14
  7. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/pyproject.toml +19 -6
  8. datadog_lambda-8.123.0/datadog_lambda/version.py +0 -1
  9. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/LICENSE +0 -0
  10. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/LICENSE-3rdparty.csv +0 -0
  11. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/NOTICE +0 -0
  12. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/README.md +0 -0
  13. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/__init__.py +0 -0
  14. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/api.py +0 -0
  15. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/asm.py +0 -0
  16. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/cold_start.py +0 -0
  17. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/constants.py +0 -0
  18. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/dogstatsd.py +0 -0
  19. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/extension.py +0 -0
  20. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/handler.py +0 -0
  21. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/logger.py +0 -0
  22. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/metric.py +0 -0
  23. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/module_name.py +0 -0
  24. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/patch.py +0 -0
  25. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/span_pointers.py +0 -0
  26. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/stats_writer.py +0 -0
  27. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/statsd_writer.py +0 -0
  28. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/tag_object.py +0 -0
  29. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/tags.py +0 -0
  30. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/thread_stats_writer.py +0 -0
  31. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/trigger.py +0 -0
  32. {datadog_lambda-8.123.0 → datadog_lambda-8.125.0}/datadog_lambda/xray.py +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: datadog_lambda
3
- Version: 8.123.0
3
+ Version: 8.125.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
7
7
  Keywords: datadog,aws,lambda,layer
8
8
  Author: Datadog, Inc.
9
9
  Author-email: dev@datadoghq.com
10
- Requires-Python: >=3.8.0,<4
10
+ Requires-Python: >=3.8.0,<3.15
11
11
  Classifier: License :: OSI Approved :: Apache Software License
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.8
@@ -21,12 +21,17 @@ Provides-Extra: dev
21
21
  Requires-Dist: botocore (>=1.34.0,<2.0.0) ; extra == "dev"
22
22
  Requires-Dist: datadog (>=0.51.0,<1.0.0)
23
23
  Requires-Dist: ddtrace (>=3.19.1,<4) ; python_version >= "3.8" and python_version < "3.10"
24
- Requires-Dist: ddtrace (>=4.1.1,<5) ; python_version >= "3.10"
24
+ Requires-Dist: ddtrace (>=4.1.1,<5,!=4.6.*) ; python_version >= "3.10"
25
25
  Requires-Dist: flake8 (>=5.0.4,<6.0.0) ; extra == "dev"
26
- Requires-Dist: pytest (>=8.0.0,<9.0.0) ; extra == "dev"
26
+ Requires-Dist: pytest (>=8.3.4,<9.0.0) ; (python_version >= "3.8" and python_version < "3.10") and (extra == "dev")
27
+ Requires-Dist: pytest (>=9.0.3,<10.0.0) ; (python_version >= "3.10") and (extra == "dev")
27
28
  Requires-Dist: pytest-benchmark (>=4.0,<5.0) ; extra == "dev"
28
- Requires-Dist: requests (>=2.22.0,<3.0.0) ; extra == "dev"
29
- Requires-Dist: ujson (>=5.9.0)
29
+ Requires-Dist: requests (>=2.22.0,<3.0.0) ; (python_version >= "3.8" and python_version < "3.10") and (extra == "dev")
30
+ Requires-Dist: requests (>=2.33.0,<3.0.0) ; (python_version >= "3.10") and (extra == "dev")
31
+ Requires-Dist: ujson (>=5.10.0,<5.12.0) ; python_version >= "3.8" and python_version < "3.10"
32
+ Requires-Dist: ujson (>=5.12.0,<6.0.0) ; python_version >= "3.10"
33
+ Requires-Dist: urllib3 (>=1.25.4,<1.27) ; python_version >= "3.8" and python_version < "3.10"
34
+ Requires-Dist: urllib3 (>=2.6.3,<3.0.0) ; python_version >= "3.10"
30
35
  Requires-Dist: wrapt (>=1.11.2,<2.0.0)
31
36
  Project-URL: Repository, https://github.com/DataDog/datadog-lambda-python
32
37
  Description-Content-Type: text/markdown
@@ -141,6 +141,17 @@ if config.is_gov_region or config.fips_mode_enabled:
141
141
  "enabled" if config.fips_mode_enabled else "not enabled",
142
142
  )
143
143
 
144
+ # Remote configuration relies on /dev/shm which is unavailable in Lambda.
145
+ # Disable it before ddtrace loads to avoid the shared-memory warning.
146
+ if "DD_REMOTE_CONFIGURATION_ENABLED" not in os.environ:
147
+ os.environ["DD_REMOTE_CONFIGURATION_ENABLED"] = "false"
148
+
149
+ # disable css to prevent double counting in lambda
150
+ os.environ["DD_TRACE_STATS_COMPUTATION_ENABLED"] = "false"
151
+
152
+ # unset css aliases to ensure it is disabled
153
+ if "DD_TRACE_COMPUTE_STATS" in os.environ:
154
+ del os.environ["DD_TRACE_COMPUTE_STATS"]
144
155
 
145
156
  if (
146
157
  "DD_INSTRUMENTATION_TELEMETRY_ENABLED" not in os.environ
@@ -41,9 +41,29 @@ def extract_durable_function_tags(event):
41
41
  if not parsed:
42
42
  logger.error("Failed to parse DurableExecutionArn: %s", durable_execution_arn)
43
43
  return {}
44
-
45
44
  execution_name, execution_id = parsed
45
+ # Use the number of operations to determine if it's the first invocation. This is
46
+ # what the durable execution SDK does to determine the replay status.
47
+ operations = event.get("InitialExecutionState", {}).get("Operations", [])
48
+ is_first_invocation = len(operations) == 1
46
49
  return {
47
- "durable_function_execution_name": execution_name,
48
- "durable_function_execution_id": execution_id,
50
+ "aws_lambda.durable_function.execution_name": execution_name,
51
+ "aws_lambda.durable_function.execution_id": execution_id,
52
+ "aws_lambda.durable_function.first_invocation": str(
53
+ is_first_invocation
54
+ ).lower(),
49
55
  }
56
+
57
+
58
+ VALID_DURABLE_STATUSES = {"SUCCEEDED", "FAILED", "PENDING"}
59
+
60
+
61
+ def extract_durable_execution_status(response, event):
62
+ if not isinstance(event, dict) or "DurableExecutionArn" not in event:
63
+ return None
64
+ if not isinstance(response, dict):
65
+ return None
66
+ status = response.get("Status")
67
+ if status not in VALID_DURABLE_STATUSES:
68
+ return None
69
+ return status
@@ -977,16 +977,12 @@ def process_injected_data(event, request_time_epoch_ms, args, tags):
977
977
  start_time_ns = int(
978
978
  injected_authorizer_data.get(Headers.Parent_Span_Finish_Time)
979
979
  )
980
- finish_time_ns = (
981
- request_time_epoch_ms
982
- + (
983
- int(
984
- event["requestContext"]["authorizer"].get(
985
- "integrationLatency", 0
986
- )
987
- )
988
- )
989
- ) * 1e6
980
+ integration_latency = int(
981
+ event["requestContext"]["authorizer"].get("integrationLatency", 0)
982
+ )
983
+ finish_time_ns = max(
984
+ start_time_ns, (request_time_epoch_ms + integration_latency) * 1e6
985
+ )
990
986
  upstream_authorizer_span = insert_upstream_authorizer_span(
991
987
  args, tags, start_time_ns, finish_time_ns
992
988
  )
@@ -1460,6 +1456,7 @@ def create_function_execution_span(
1460
1456
  function_arn = ":".join(tk[0:7]) if len(tk) > 7 else function_arn
1461
1457
  function_version = tk[7] if len(tk) > 7 else "$LATEST"
1462
1458
  tags = {
1459
+ "span.kind": "server",
1463
1460
  "cold_start": str(is_cold_start).lower(),
1464
1461
  "function_arn": function_arn,
1465
1462
  "function_version": function_version,
@@ -0,0 +1 @@
1
+ __version__ = "8.125.0"
@@ -42,7 +42,10 @@ from datadog_lambda.tracing import (
42
42
  tracer,
43
43
  propagator,
44
44
  )
45
- from datadog_lambda.durable import extract_durable_function_tags
45
+ from datadog_lambda.durable import (
46
+ extract_durable_function_tags,
47
+ extract_durable_execution_status,
48
+ )
46
49
  from datadog_lambda.trigger import (
47
50
  extract_trigger_tags,
48
51
  extract_http_status_code_tag,
@@ -153,7 +156,7 @@ class _LambdaDecorator(object):
153
156
  if config.trace_extractor:
154
157
  extractor_parts = config.trace_extractor.rsplit(".", 1)
155
158
  if len(extractor_parts) == 2:
156
- (mod_name, extractor_name) = extractor_parts
159
+ mod_name, extractor_name = extractor_parts
157
160
  modified_extractor_name = modify_module_name(mod_name)
158
161
  extractor_module = import_module(modified_extractor_name)
159
162
  self.trace_extractor = getattr(extractor_module, extractor_name)
@@ -188,7 +191,6 @@ class _LambdaDecorator(object):
188
191
  if self.blocking_response:
189
192
  return self.blocking_response
190
193
  self.response = self.func(event, context, **kwargs)
191
- return self.response
192
194
  except BlockingException:
193
195
  self.blocking_response = get_asm_blocked_response(self.event_source)
194
196
  except Exception:
@@ -201,8 +203,9 @@ class _LambdaDecorator(object):
201
203
  raise
202
204
  finally:
203
205
  self._after(event, context)
204
- if self.blocking_response:
205
- return self.blocking_response
206
+ if self.blocking_response:
207
+ return self.blocking_response
208
+ return self.response
206
209
 
207
210
  def _inject_authorizer_span_headers(self, request_id):
208
211
  reference_span = self.inferred_span if self.inferred_span else self.span
@@ -305,6 +308,16 @@ class _LambdaDecorator(object):
305
308
 
306
309
  status_code = extract_http_status_code_tag(self.trigger_tags, self.response)
307
310
 
311
+ # Skip creating cold start spans in managed instances mode
312
+ # In managed instances, the tracer library handles cold start independently
313
+ should_trace_cold_start = (
314
+ config.cold_start_tracing
315
+ and is_new_sandbox()
316
+ and not is_managed_instances_mode()
317
+ )
318
+ if should_trace_cold_start:
319
+ trace_ctx = tracer.current_trace_context()
320
+
308
321
  if self.span:
309
322
  if config.appsec_enabled and not self.blocking_response:
310
323
  asm_start_response(
@@ -330,6 +343,13 @@ class _LambdaDecorator(object):
330
343
  if status_code:
331
344
  self.span.set_tag("http.status_code", status_code)
332
345
 
346
+ durable_status = extract_durable_execution_status(self.response, event)
347
+ if durable_status:
348
+ self.span.set_tag(
349
+ "aws_lambda.durable_function.execution_status",
350
+ durable_status,
351
+ )
352
+
333
353
  self.span.finish()
334
354
 
335
355
  if status_code:
@@ -342,15 +362,6 @@ class _LambdaDecorator(object):
342
362
  create_dd_dummy_metadata_subsegment(
343
363
  self.trigger_tags, XraySubsegment.LAMBDA_FUNCTION_TAGS_KEY
344
364
  )
345
- # Skip creating cold start spans in managed instances mode
346
- # In managed instances, the tracer library handles cold start independently
347
- should_trace_cold_start = (
348
- config.cold_start_tracing
349
- and is_new_sandbox()
350
- and not is_managed_instances_mode()
351
- )
352
- if should_trace_cold_start:
353
- trace_ctx = tracer.current_trace_context()
354
365
 
355
366
  if self.inferred_span:
356
367
  if status_code:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "datadog_lambda"
3
- version = "8.123.0"
3
+ version = "8.125.0"
4
4
  description = "The Datadog AWS Lambda Library"
5
5
  authors = ["Datadog, Inc. <dev@datadoghq.com>"]
6
6
  license = "Apache-2.0"
@@ -26,17 +26,30 @@ classifiers = [
26
26
  ]
27
27
 
28
28
  [tool.poetry.dependencies]
29
- python = ">=3.8.0,<4"
29
+ python = ">=3.8.0,<3.15"
30
30
  datadog = ">=0.51.0,<1.0.0"
31
31
  wrapt = "^1.11.2"
32
32
  ddtrace = [
33
33
  {version = ">=3.19.1,<4", python = ">=3.8,<3.10"},
34
- {version = ">=4.1.1,<5", python = ">=3.10"}
34
+ {version = ">=4.1.1,<5,!=4.6.*", python = ">=3.10"}
35
+ ]
36
+ ujson = [
37
+ {version = ">=5.10.0,<5.12.0", python = ">=3.8,<3.10"},
38
+ {version = "^5.12.0", python = ">=3.10"},
39
+ ]
40
+ urllib3 = [
41
+ {version = ">=1.25.4,<1.27", python = ">=3.8,<3.10"},
42
+ {version = "^2.6.3", python = ">=3.10"},
35
43
  ]
36
- ujson = ">=5.9.0"
37
44
  botocore = { version = "^1.34.0", optional = true }
38
- requests = { version ="^2.22.0", optional = true }
39
- pytest = { version= "^8.0.0", optional = true }
45
+ requests = [
46
+ { version = "^2.22.0", optional = true, python = ">=3.8,<3.10" },
47
+ { version = "^2.33.0", optional = true, python = ">=3.10" },
48
+ ]
49
+ pytest = [
50
+ { version = "^8.3.4", optional = true, python = ">=3.8,<3.10" },
51
+ { version = "^9.0.3", optional = true, python = ">=3.10" },
52
+ ]
40
53
  pytest-benchmark = { version = "^4.0", optional = true }
41
54
  flake8 = { version = "^5.0.4", optional = true }
42
55
 
@@ -1 +0,0 @@
1
- __version__ = "8.123.0"