diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 26b4b78e..a7f48dfe 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,6 +1 @@
-* @DataDog/serverless-aws
-datadog_lambda/tracing.py @DataDog/apm-serverless
-datadog_lambda/patch.py @DataDog/apm-serverless
-datadog_lambda/span_points.py @DataDog/apm-serverless
-datadog_lambda/cold_start.py @DataDog/apm-serverless
-datadog_lambda/wrapper.py @DataDog/apm-serverless
+* @DataDog/serverless-aws @DataDog/apm-serverless
diff --git a/.github/workflows/update_deps.yml b/.github/workflows/update_deps.yml
index 31025402..33a524b2 100644
--- a/.github/workflows/update_deps.yml
+++ b/.github/workflows/update_deps.yml
@@ -3,14 +3,24 @@ name: update-deps
on:
schedule:
- cron: "0 10 * * *" # Run at 10 am every day
+ workflow_dispatch:
jobs:
check:
runs-on: ubuntu-latest
+ environment:
+ name: protected-main-env
steps:
+ - name: Generate token
+ id: generate_token
+ uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
+ with:
+ app-id: ${{ secrets.GH_APP_ID }}
+ private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
+
- uses: actions/checkout@v3
with:
- ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
+ token: ${{ steps.generate_token.outputs.token }}
- name: Set up Python
uses: actions/setup-python@v4
diff --git a/CODEOWNERS b/CODEOWNERS
deleted file mode 100644
index e340f1ed..00000000
--- a/CODEOWNERS
+++ /dev/null
@@ -1 +0,0 @@
-* @DataDog/serverless
\ No newline at end of file
diff --git a/README.md b/README.md
index 03cd846a..658babc2 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,7 @@ Besides the environment variables supported by dd-trace-py, the datadog-lambda-p
| DD_COLD_START_TRACE_SKIP_LIB | optionally skip creating Cold Start Spans for a comma-separated list of libraries. Useful to limit depth or skip known libraries. | `ddtrace.internal.compat,ddtrace.filters` |
| DD_CAPTURE_LAMBDA_PAYLOAD | [Captures incoming and outgoing AWS Lambda payloads][1] in the Datadog APM spans for Lambda invocations. | `false` |
| DD_CAPTURE_LAMBDA_PAYLOAD_MAX_DEPTH | Determines the level of detail captured from AWS Lambda payloads, which are then assigned as tags for the `aws.lambda` span. It specifies the nesting depth of the JSON payload structure to process. Once the specified maximum depth is reached, the tag's value is set to the stringified value of any nested elements beyond this level.
For example, given the input payload:
{
"lv1" : {
"lv2": {
"lv3": "val"
}
}
}
If the depth is set to `2`, the resulting tag's key is set to `function.request.lv1.lv2` and the value is `{\"lv3\": \"val\"}`.
If the depth is set to `0`, the resulting tag's key is set to `function.request` and value is `{\"lv1\":{\"lv2\":{\"lv3\": \"val\"}}}` | `10` |
+| DD_EXCEPTION_REPLAY_ENABLED | When set to `true`, the Lambda will run with Error Tracking Exception Replay enabled, capturing local variables. | `false` |
## Opening Issues
diff --git a/datadog_lambda/dogstatsd.py b/datadog_lambda/dogstatsd.py
index f30a2039..a08e2592 100644
--- a/datadog_lambda/dogstatsd.py
+++ b/datadog_lambda/dogstatsd.py
@@ -97,7 +97,7 @@ def _serialize_metric(self, metric, metric_type, value, tags, timestamp):
value,
metric_type,
("|#" + ",".join(self.normalize_tags(tags))) if tags else "",
- ("|T" + str(timestamp)) if timestamp is not None else "",
+ ("|T" + str(int(timestamp))) if timestamp is not None else "",
)
def _report(self, metric, metric_type, value, tags, timestamp):
diff --git a/datadog_lambda/dsm.py b/datadog_lambda/dsm.py
new file mode 100644
index 00000000..427f5e47
--- /dev/null
+++ b/datadog_lambda/dsm.py
@@ -0,0 +1,38 @@
+from datadog_lambda import logger
+from datadog_lambda.trigger import EventTypes
+
+
+def set_dsm_context(event, event_source):
+
+ if event_source.equals(EventTypes.SQS):
+ _dsm_set_sqs_context(event)
+
+
+def _dsm_set_sqs_context(event):
+ from datadog_lambda.wrapper import format_err_with_traceback
+ from ddtrace.internal.datastreams import data_streams_processor
+ from ddtrace.internal.datastreams.processor import DsmPathwayCodec
+ from ddtrace.internal.datastreams.botocore import (
+ get_datastreams_context,
+ calculate_sqs_payload_size,
+ )
+
+ records = event.get("Records")
+ if records is None:
+ return
+ processor = data_streams_processor()
+
+ for record in records:
+ try:
+ queue_arn = record.get("eventSourceARN", "")
+
+ contextjson = get_datastreams_context(record)
+ payload_size = calculate_sqs_payload_size(record)
+
+ ctx = DsmPathwayCodec.decode(contextjson, processor)
+ ctx.set_checkpoint(
+ ["direction:in", f"topic:{queue_arn}", "type:sqs"],
+ payload_size=payload_size,
+ )
+ except Exception as e:
+ logger.error(format_err_with_traceback(e))
diff --git a/datadog_lambda/metric.py b/datadog_lambda/metric.py
index 0c18b517..c9b978d6 100644
--- a/datadog_lambda/metric.py
+++ b/datadog_lambda/metric.py
@@ -111,6 +111,18 @@ def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=Fal
if isinstance(timestamp, datetime):
timestamp = int(timestamp.timestamp())
+ else:
+ try:
+ timestamp = int(timestamp)
+ except Exception:
+ logger.debug(
+ "Ignoring metric submission for metric '%s' because the timestamp cannot "
+ "be turned into an integer: %r",
+ metric_name,
+ timestamp,
+ )
+ return
+
timestamp_floor = int((datetime.now() - timedelta(hours=4)).timestamp())
if timestamp < timestamp_floor:
logger.warning(
diff --git a/datadog_lambda/tracing.py b/datadog_lambda/tracing.py
index 9a27673c..4b6f300a 100644
--- a/datadog_lambda/tracing.py
+++ b/datadog_lambda/tracing.py
@@ -850,13 +850,14 @@ def create_inferred_span_from_lambda_function_url_event(event, context):
http = request_context.get("http")
method = http.get("method") if http else None
path = http.get("path") if http else None
+ http_url = f"https://{domain}{path}"
resource = f"{method} {path}"
tags = {
"operation_name": "aws.lambda.url",
- "http.url": domain + path,
+ "http.url": http_url,
"endpoint": path,
"http.method": method,
- "resource_names": domain + path,
+ "resource_names": resource,
"request_id": context.aws_request_id,
}
request_time_epoch = request_context.get("timeEpoch")
@@ -948,6 +949,7 @@ def create_inferred_span_from_api_gateway_websocket_event(
request_context = event.get("requestContext")
domain = request_context.get("domainName")
endpoint = request_context.get("routeKey")
+ http_url = f"https://{domain}{endpoint}"
api_id = request_context.get("apiId")
service_name = determine_service_name(
@@ -955,7 +957,7 @@ def create_inferred_span_from_api_gateway_websocket_event(
)
tags = {
"operation_name": "aws.apigateway.websocket",
- "http.url": domain + endpoint,
+ "http.url": http_url,
"endpoint": endpoint,
"resource_names": endpoint,
"apiid": api_id,
@@ -1007,11 +1009,12 @@ def create_inferred_span_from_api_gateway_event(
)
method = event.get("httpMethod")
path = event.get("path")
+ http_url = f"https://{domain}{path}"
resource_path = _get_resource_path(event, request_context)
resource = f"{method} {resource_path}"
tags = {
"operation_name": "aws.apigateway.rest",
- "http.url": domain + path,
+ "http.url": http_url,
"endpoint": path,
"http.method": method,
"resource_names": resource,
@@ -1073,12 +1076,13 @@ def create_inferred_span_from_http_api_event(
http = request_context.get("http") or {}
method = http.get("method")
path = event.get("rawPath")
+ http_url = f"https://{domain}{path}"
resource_path = _get_resource_path(event, request_context)
resource = f"{method} {resource_path}"
tags = {
"operation_name": "aws.httpapi",
"endpoint": path,
- "http.url": domain + path,
+ "http.url": http_url,
"http.method": http.get("method"),
"http.protocol": http.get("protocol"),
"http.source_ip": http.get("sourceIp"),
diff --git a/datadog_lambda/trigger.py b/datadog_lambda/trigger.py
index 8090e36e..14cb06ac 100644
--- a/datadog_lambda/trigger.py
+++ b/datadog_lambda/trigger.py
@@ -114,10 +114,14 @@ def parse_event_source(event: dict) -> _EventSource:
event_source = None
+ # Get requestContext safely and ensure it's a dictionary
request_context = event.get("requestContext")
+ if not isinstance(request_context, dict):
+ request_context = None
+
if request_context and request_context.get("stage"):
if "domainName" in request_context and detect_lambda_function_url_domain(
- request_context.get("domainName")
+ request_context.get("domainName", "")
):
return _EventSource(EventTypes.LAMBDA_FUNCTION_URL)
event_source = _EventSource(EventTypes.API_GATEWAY)
@@ -171,6 +175,8 @@ def parse_event_source(event: dict) -> _EventSource:
def detect_lambda_function_url_domain(domain: str) -> bool:
# e.g. "etsn5fibjr.lambda-url.eu-south-1.amazonaws.com"
+ if not isinstance(domain, str):
+ return False
domain_parts = domain.split(".")
if len(domain_parts) < 2:
return False
@@ -283,17 +289,28 @@ def extract_http_tags(event):
Extracts HTTP facet tags from the triggering event
"""
http_tags = {}
+
+ # Safely get request_context and ensure it's a dictionary
request_context = event.get("requestContext")
+ if not isinstance(request_context, dict):
+ request_context = None
+
path = event.get("path")
method = event.get("httpMethod")
+
if request_context and request_context.get("stage"):
- if request_context.get("domainName"):
- http_tags["http.url"] = request_context.get("domainName")
+ domain_name = request_context.get("domainName")
+ if domain_name:
+ http_tags["http.url"] = f"https://{domain_name}"
path = request_context.get("path")
method = request_context.get("httpMethod")
+
# Version 2.0 HTTP API Gateway
- apigateway_v2_http = request_context.get("http")
+ apigateway_v2_http = request_context.get("http", {})
+ if not isinstance(apigateway_v2_http, dict):
+ apigateway_v2_http = {}
+
if event.get("version") == "2.0" and apigateway_v2_http:
path = apigateway_v2_http.get("path")
method = apigateway_v2_http.get("method")
@@ -303,15 +320,23 @@ def extract_http_tags(event):
if method:
http_tags["http.method"] = method
- headers = event.get("headers")
+ # Safely get headers
+ headers = event.get("headers", {})
+ if not isinstance(headers, dict):
+ headers = {}
+
if headers and headers.get("Referer"):
http_tags["http.referer"] = headers.get("Referer")
# Try to get `routeKey` from API GW v2; otherwise try to get `resource` from API GW v1
route = event.get("routeKey") or event.get("resource")
- if route:
- # "GET /my/endpoint" = > "/my/endpoint"
- http_tags["http.route"] = route.split(" ")[-1]
+ if route and isinstance(route, str):
+ try:
+ # "GET /my/endpoint" = > "/my/endpoint"
+ http_tags["http.route"] = route.split(" ")[-1]
+ except Exception:
+ # If splitting fails, use the route as is
+ http_tags["http.route"] = route
return http_tags
diff --git a/datadog_lambda/version.py b/datadog_lambda/version.py
index bcd37def..9534f0c7 100644
--- a/datadog_lambda/version.py
+++ b/datadog_lambda/version.py
@@ -1 +1 @@
-__version__ = "6.108.0"
+__version__ = "6.110.0"
diff --git a/datadog_lambda/wrapper.py b/datadog_lambda/wrapper.py
index e81b1baa..0e23b721 100644
--- a/datadog_lambda/wrapper.py
+++ b/datadog_lambda/wrapper.py
@@ -9,6 +9,7 @@
from importlib import import_module
from time import time_ns
+from datadog_lambda.dsm import set_dsm_context
from datadog_lambda.extension import should_use_extension, flush_extension
from datadog_lambda.cold_start import (
set_cold_start,
@@ -53,6 +54,13 @@
if llmobs_env_var:
from ddtrace.llmobs import LLMObs
+exception_replay_env_var = os.environ.get(
+ "DD_EXCEPTION_REPLAY_ENABLED", "false"
+).lower() in ("true", "1")
+if exception_replay_env_var:
+ from ddtrace.debugging._exception.replay import SpanExceptionHandler
+ from ddtrace.debugging._uploader import LogsIntakeUploaderV1
+
logger = logging.getLogger(__name__)
DD_FLUSH_TO_LOG = "DD_FLUSH_TO_LOG"
@@ -72,6 +80,7 @@
DD_REQUESTS_SERVICE_NAME = "DD_REQUESTS_SERVICE_NAME"
DD_SERVICE = "DD_SERVICE"
DD_ENV = "DD_ENV"
+DD_DATA_STREAMS_ENABLED = "DD_DATA_STREAMS_ENABLED"
def get_env_as_int(env_key, default_value: int) -> int:
@@ -183,6 +192,9 @@ def __init__(self, func):
self.min_cold_start_trace_duration = get_env_as_int(
DD_MIN_COLD_START_DURATION, 3
)
+ self.data_streams_enabled = (
+ os.environ.get(DD_DATA_STREAMS_ENABLED, "false").lower() == "true"
+ )
self.local_testing_mode = os.environ.get(
DD_LOCAL_TEST, "false"
).lower() in ("true", "1")
@@ -224,6 +236,11 @@ def __init__(self, func):
if llmobs_env_var:
LLMObs.enable()
+ # Enable Exception Replay
+ if exception_replay_env_var:
+ logger.debug("Enabling exception replay")
+ SpanExceptionHandler.enable()
+
logger.debug("datadog_lambda_wrapper initialized")
except Exception as e:
logger.error(format_err_with_traceback(e))
@@ -310,6 +327,8 @@ def _before(self, event, context):
self.inferred_span = create_inferred_span(
event, context, event_source, self.decode_authorizer_context
)
+ if self.data_streams_enabled:
+ set_dsm_context(event, event_source)
self.span = create_function_execution_span(
context=context,
function_name=self.function_name,
@@ -394,6 +413,10 @@ def _after(self, event, context):
if llmobs_env_var:
LLMObs.flush()
+ # Flush exception replay
+ if exception_replay_env_var:
+ LogsIntakeUploaderV1._instance.periodic()
+
if self.encode_authorizer_context and is_authorizer_response(self.response):
self._inject_authorizer_span_headers(
event.get("requestContext", {}).get("requestId")
diff --git a/pyproject.toml b/pyproject.toml
index 8f16b438..ba5bcb17 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "datadog_lambda"
-version = "6.108.0"
+version = "6.110.0"
description = "The Datadog AWS Lambda Library"
authors = ["Datadog, Inc. "]
license = "Apache-2.0"
diff --git a/tests/integration/snapshots/logs/async-metrics_python310.log b/tests/integration/snapshots/logs/async-metrics_python310.log
index 24d3fb5b..0bd7237c 100644
--- a/tests/integration/snapshots/logs/async-metrics_python310.log
+++ b/tests/integration/snapshots/logs/async-metrics_python310.log
@@ -55,7 +55,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -103,7 +103,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -594,7 +594,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -644,7 +644,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1436,7 +1436,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1486,7 +1486,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/async-metrics_python311.log b/tests/integration/snapshots/logs/async-metrics_python311.log
index e4fa66bc..8550a062 100644
--- a/tests/integration/snapshots/logs/async-metrics_python311.log
+++ b/tests/integration/snapshots/logs/async-metrics_python311.log
@@ -55,7 +55,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -103,7 +103,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -594,7 +594,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -644,7 +644,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1436,7 +1436,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1486,7 +1486,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/async-metrics_python312.log b/tests/integration/snapshots/logs/async-metrics_python312.log
index 0d632c6c..57c318ab 100644
--- a/tests/integration/snapshots/logs/async-metrics_python312.log
+++ b/tests/integration/snapshots/logs/async-metrics_python312.log
@@ -55,7 +55,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -103,7 +103,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -594,7 +594,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -644,7 +644,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1436,7 +1436,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1486,7 +1486,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/async-metrics_python313.log b/tests/integration/snapshots/logs/async-metrics_python313.log
index 09070709..9204499b 100644
--- a/tests/integration/snapshots/logs/async-metrics_python313.log
+++ b/tests/integration/snapshots/logs/async-metrics_python313.log
@@ -55,7 +55,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -103,7 +103,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -594,7 +594,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -644,7 +644,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1436,7 +1436,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1486,7 +1486,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/async-metrics_python38.log b/tests/integration/snapshots/logs/async-metrics_python38.log
index 4a506930..e6df054c 100644
--- a/tests/integration/snapshots/logs/async-metrics_python38.log
+++ b/tests/integration/snapshots/logs/async-metrics_python38.log
@@ -55,7 +55,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -103,7 +103,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -594,7 +594,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -644,7 +644,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1436,7 +1436,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1486,7 +1486,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/async-metrics_python39.log b/tests/integration/snapshots/logs/async-metrics_python39.log
index 54081402..9bcb7a85 100644
--- a/tests/integration/snapshots/logs/async-metrics_python39.log
+++ b/tests/integration/snapshots/logs/async-metrics_python39.log
@@ -55,7 +55,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -103,7 +103,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -594,7 +594,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -644,7 +644,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1436,7 +1436,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1486,7 +1486,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/sync-metrics_python310.log b/tests/integration/snapshots/logs/sync-metrics_python310.log
index e2569775..40562a6d 100644
--- a/tests/integration/snapshots/logs/sync-metrics_python310.log
+++ b/tests/integration/snapshots/logs/sync-metrics_python310.log
@@ -35,7 +35,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -83,7 +83,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -631,7 +631,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -681,7 +681,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1568,7 +1568,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1618,7 +1618,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/sync-metrics_python311.log b/tests/integration/snapshots/logs/sync-metrics_python311.log
index 69d4a695..52ec4c85 100644
--- a/tests/integration/snapshots/logs/sync-metrics_python311.log
+++ b/tests/integration/snapshots/logs/sync-metrics_python311.log
@@ -35,7 +35,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -83,7 +83,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -631,7 +631,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -681,7 +681,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1568,7 +1568,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1618,7 +1618,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/sync-metrics_python312.log b/tests/integration/snapshots/logs/sync-metrics_python312.log
index 49bae0a2..3ec0f01f 100644
--- a/tests/integration/snapshots/logs/sync-metrics_python312.log
+++ b/tests/integration/snapshots/logs/sync-metrics_python312.log
@@ -35,7 +35,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -83,7 +83,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -631,7 +631,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -681,7 +681,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1568,7 +1568,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1618,7 +1618,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/sync-metrics_python313.log b/tests/integration/snapshots/logs/sync-metrics_python313.log
index 2f461f6f..d2c20dc0 100644
--- a/tests/integration/snapshots/logs/sync-metrics_python313.log
+++ b/tests/integration/snapshots/logs/sync-metrics_python313.log
@@ -35,7 +35,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -83,7 +83,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -631,7 +631,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -681,7 +681,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1568,7 +1568,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1618,7 +1618,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/sync-metrics_python38.log b/tests/integration/snapshots/logs/sync-metrics_python38.log
index 83e33d33..57a354a6 100644
--- a/tests/integration/snapshots/logs/sync-metrics_python38.log
+++ b/tests/integration/snapshots/logs/sync-metrics_python38.log
@@ -35,7 +35,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -83,7 +83,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -631,7 +631,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -681,7 +681,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1568,7 +1568,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1618,7 +1618,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/integration/snapshots/logs/sync-metrics_python39.log b/tests/integration/snapshots/logs/sync-metrics_python39.log
index 0a433c34..8b7bb31b 100644
--- a/tests/integration/snapshots/logs/sync-metrics_python39.log
+++ b/tests/integration/snapshots/logs/sync-metrics_python39.log
@@ -35,7 +35,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.rest",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com/",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com/",
"endpoint": "/",
"http.method": "GET",
"resource_names": "GET /",
@@ -83,7 +83,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/Prod/",
"http.method": "GET",
"http.route": "/",
@@ -377,7 +377,6 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
]
}
HTTP POST https://api.datadoghq.com/api/v1/distribution_points Headers: ["Accept-Encoding:gzip, deflate","Accept:*/*","Connection:keep-alive","Content-Encoding:deflate","Content-Length:XXXX","Content-Type:application/json","DD-API-KEY:XXXX","User-Agent:datadogpy/XX (python XX; os linux; arch XXXX)","traceparent:XXX","tracestate:XXX
-END Duration: XXXX ms Memory Used: XXXX MB
{
"traces": [
[
@@ -416,6 +415,7 @@ END Duration: XXXX ms Memory Used: XXXX MB
]
]
}
+END Duration: XXXX ms Memory Used: XXXX MB
START
{
"m": "aws.lambda.enhanced.invocations",
@@ -631,7 +631,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"_dd.origin": "lambda",
"operation_name": "aws.httpapi",
"endpoint": "/httpapi/get",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "XXXX",
@@ -681,7 +681,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX$default",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -1568,7 +1568,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"runtime-id": "XXXX",
"_dd.origin": "lambda",
"operation_name": "aws.apigateway.websocket",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com$default",
"endpoint": "$default",
"resource_names": "$default",
"apiid": "XXXX",
@@ -1618,7 +1618,7 @@ HTTP GET https://www.datadoghq.com/ Headers: ["Accept-Encoding:gzip, deflate","A
"span.name": "aws.lambda",
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "XXXX",
- "http.url": "XXXX.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://XXXX.execute-api.eu-west-1.amazonaws.com",
"http.status_code": "200",
"_dd.base_service": "integration-tests-python"
},
diff --git a/tests/test_dogstatsd.py b/tests/test_dogstatsd.py
index ea6afd48..6fe79372 100644
--- a/tests/test_dogstatsd.py
+++ b/tests/test_dogstatsd.py
@@ -53,3 +53,7 @@ def test_distribution_with_tags(self):
def test_distribution_with_timestamp(self):
statsd.distribution("my.test.timestamp.metric", 9, timestamp=123456789)
self._checkOnlyOneMetric("my.test.timestamp.metric:9|d|T123456789")
+
+ def test_distribution_with_float_timestamp(self):
+ statsd.distribution("my.test.timestamp.metric", 9, timestamp=123456789.123)
+ self._checkOnlyOneMetric("my.test.timestamp.metric:9|d|T123456789")
diff --git a/tests/test_dsm.py b/tests/test_dsm.py
new file mode 100644
index 00000000..544212d8
--- /dev/null
+++ b/tests/test_dsm.py
@@ -0,0 +1,112 @@
+import unittest
+from unittest.mock import patch, MagicMock
+
+from datadog_lambda.dsm import set_dsm_context, _dsm_set_sqs_context
+from datadog_lambda.trigger import EventTypes, _EventSource
+
+
+class TestDsmSQSContext(unittest.TestCase):
+ def setUp(self):
+ patcher = patch("datadog_lambda.dsm._dsm_set_sqs_context")
+ self.mock_dsm_set_sqs_context = patcher.start()
+ self.addCleanup(patcher.stop)
+
+ patcher = patch("ddtrace.internal.datastreams.data_streams_processor")
+ self.mock_data_streams_processor = patcher.start()
+ self.addCleanup(patcher.stop)
+
+ patcher = patch("ddtrace.internal.datastreams.botocore.get_datastreams_context")
+ self.mock_get_datastreams_context = patcher.start()
+ self.mock_get_datastreams_context.return_value = {}
+ self.addCleanup(patcher.stop)
+
+ patcher = patch(
+ "ddtrace.internal.datastreams.botocore.calculate_sqs_payload_size"
+ )
+ self.mock_calculate_sqs_payload_size = patcher.start()
+ self.mock_calculate_sqs_payload_size.return_value = 100
+ self.addCleanup(patcher.stop)
+
+ patcher = patch("ddtrace.internal.datastreams.processor.DsmPathwayCodec.decode")
+ self.mock_dsm_pathway_codec_decode = patcher.start()
+ self.addCleanup(patcher.stop)
+
+ def test_non_sqs_event_source_does_nothing(self):
+ """Test that non-SQS event sources don't trigger DSM context setting"""
+ event = {}
+ # Use Unknown Event Source
+ event_source = _EventSource(EventTypes.UNKNOWN)
+ set_dsm_context(event, event_source)
+
+ # DSM context should not be set for non-SQS events
+ self.mock_dsm_set_sqs_context.assert_not_called()
+
+ def test_sqs_event_with_no_records_does_nothing(self):
+ """Test that events where Records is None don't trigger DSM processing"""
+ events_with_no_records = [
+ {},
+ {"Records": None},
+ {"someOtherField": "value"},
+ ]
+
+ for event in events_with_no_records:
+ _dsm_set_sqs_context(event)
+ self.mock_data_streams_processor.assert_not_called()
+
+ def test_sqs_event_triggers_dsm_sqs_context(self):
+ """Test that SQS event sources trigger the SQS-specific DSM context function"""
+ sqs_event = {
+ "Records": [
+ {
+ "eventSource": "aws:sqs",
+ "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:my-queue",
+ "body": "Hello from SQS!",
+ }
+ ]
+ }
+
+ event_source = _EventSource(EventTypes.SQS)
+ set_dsm_context(sqs_event, event_source)
+
+ self.mock_dsm_set_sqs_context.assert_called_once_with(sqs_event)
+
+ def test_sqs_multiple_records_process_each_record(self):
+ """Test that each record in an SQS event gets processed individually"""
+ multi_record_event = {
+ "Records": [
+ {
+ "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:queue1",
+ "body": "Message 1",
+ },
+ {
+ "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:queue2",
+ "body": "Message 2",
+ },
+ {
+ "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:queue3",
+ "body": "Message 3",
+ },
+ ]
+ }
+
+ mock_context = MagicMock()
+ self.mock_dsm_pathway_codec_decode.return_value = mock_context
+
+ _dsm_set_sqs_context(multi_record_event)
+
+ self.assertEqual(mock_context.set_checkpoint.call_count, 3)
+
+ calls = mock_context.set_checkpoint.call_args_list
+ expected_arns = [
+ "arn:aws:sqs:us-east-1:123456789012:queue1",
+ "arn:aws:sqs:us-east-1:123456789012:queue2",
+ "arn:aws:sqs:us-east-1:123456789012:queue3",
+ ]
+
+ for i, call in enumerate(calls):
+ args, kwargs = call
+ tags = args[0]
+ self.assertIn("direction:in", tags)
+ self.assertIn(f"topic:{expected_arns[i]}", tags)
+ self.assertIn("type:sqs", tags)
+ self.assertEqual(kwargs["payload_size"], 100)
diff --git a/tests/test_metric.py b/tests/test_metric.py
index a4b0be2c..e7dab2c3 100644
--- a/tests/test_metric.py
+++ b/tests/test_metric.py
@@ -111,6 +111,34 @@ def test_lambda_metric_datetime_with_extension(self):
)
self.mock_write_metric_point_to_stdout.assert_not_called()
+ @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION)
+ def test_lambda_metric_float_with_extension(self):
+ delta = timedelta(minutes=1)
+ timestamp_float = (datetime.now() - delta).timestamp()
+ timestamp_int = int(timestamp_float)
+
+ lambda_metric("test_timestamp", 1, timestamp_float)
+ self.mock_metric_lambda_stats.distribution.assert_has_calls(
+ [
+ call(
+ "test_timestamp",
+ 1,
+ timestamp=timestamp_int,
+ tags=[dd_lambda_layer_tag],
+ )
+ ]
+ )
+ self.mock_write_metric_point_to_stdout.assert_not_called()
+
+ @patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION)
+ def test_lambda_metric_timestamp_junk_with_extension(self):
+ delta = timedelta(minutes=1)
+ timestamp = (datetime.now() - delta).isoformat()
+
+ lambda_metric("test_timestamp", 1, timestamp)
+ self.mock_metric_lambda_stats.distribution.assert_not_called()
+ self.mock_write_metric_point_to_stdout.assert_not_called()
+
@patch("datadog_lambda.metric.metrics_handler", MetricsHandler.EXTENSION)
def test_lambda_metric_invalid_timestamp_with_extension(self):
delta = timedelta(hours=5)
diff --git a/tests/test_tracing.py b/tests/test_tracing.py
index 0a961a62..e38e4ecd 100644
--- a/tests/test_tracing.py
+++ b/tests/test_tracing.py
@@ -1730,7 +1730,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "1234567890",
"endpoint": "/path/to/resource",
"http.method": "POST",
- "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource",
+ "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "POST /{proxy+}",
@@ -1752,7 +1752,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "lgxbo6a518",
"endpoint": "/http/get",
"http.method": "GET",
- "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get",
+ "http.url": "https://lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "GET /http/get",
@@ -1774,7 +1774,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "lgxbo6a518",
"endpoint": "/http/get",
"http.method": "GET",
- "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get",
+ "http.url": "https://lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "GET /http/get",
@@ -1798,7 +1798,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"http.method": "GET",
"http.protocol": "HTTP/1.1",
"http.source_ip": "38.122.226.210",
- "http.url": "x02yirxc7a.execute-api.eu-west-1.amazonaws.com/httpapi/get",
+ "http.url": "https://x02yirxc7a.execute-api.eu-west-1.amazonaws.com/httpapi/get",
"http.user_agent": "curl/7.64.1",
"operation_name": "aws.httpapi",
"request_id": "123",
@@ -1821,7 +1821,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "mcwkra0ya4",
"endpoint": "/user/42",
"http.method": "GET",
- "http.url": "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com/user/42",
+ "http.url": "https://mcwkra0ya4.execute-api.sa-east-1.amazonaws.com/user/42",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "GET /user/{id}",
@@ -1843,7 +1843,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "9vj54we5ih",
"endpoint": "/user/42",
"http.method": "GET",
- "http.url": "9vj54we5ih.execute-api.sa-east-1.amazonaws.com/user/42",
+ "http.url": "https://9vj54we5ih.execute-api.sa-east-1.amazonaws.com/user/42",
"operation_name": "aws.httpapi",
"request_id": "123",
"resource_names": "GET /user/{id}",
@@ -1866,7 +1866,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"connection_id": "Fc5SzcoYGjQCJlg=",
"endpoint": "$default",
"event_type": "MESSAGE",
- "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com$default",
+ "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com$default",
"message_direction": "IN",
"operation_name": "aws.apigateway.websocket",
"request_id": "123",
@@ -1890,7 +1890,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"connection_id": "Fc2tgfl3mjQCJfA=",
"endpoint": "$connect",
"event_type": "CONNECT",
- "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com$connect",
+ "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com$connect",
"message_direction": "IN",
"operation_name": "aws.apigateway.websocket",
"request_id": "123",
@@ -1914,7 +1914,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"connection_id": "Fc2tgfl3mjQCJfA=",
"endpoint": "$disconnect",
"event_type": "DISCONNECT",
- "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com$disconnect",
+ "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com$disconnect",
"message_direction": "IN",
"operation_name": "aws.apigateway.websocket",
"request_id": "123",
@@ -2112,7 +2112,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "None",
"endpoint": "/path/to/resource",
"http.method": "POST",
- "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource",
+ "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "POST /{proxy+}",
@@ -2135,7 +2135,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "amddr1rix9",
"endpoint": "/hello",
"http.method": "GET",
- "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
+ "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "GET /hello",
@@ -2157,7 +2157,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "amddr1rix9",
"endpoint": "/hello",
"http.method": "GET",
- "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
+ "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "GET /hello",
@@ -2180,7 +2180,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "amddr1rix9",
"endpoint": "/hello",
"http.method": "GET",
- "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
+ "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "GET /hello",
@@ -2202,7 +2202,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "amddr1rix9",
"endpoint": "/hello",
"http.method": "GET",
- "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
+ "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
"operation_name": "aws.apigateway.rest",
"request_id": "123",
"resource_names": "GET /hello",
@@ -2224,7 +2224,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "amddr1rix9",
"endpoint": "/hello",
"http.method": "GET",
- "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
+ "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
"operation_name": "aws.httpapi",
"request_id": "123",
"resource_names": "GET /hello",
@@ -2246,7 +2246,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"apiname": "amddr1rix9",
"endpoint": "/hello",
"http.method": "GET",
- "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
+ "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello",
"operation_name": "aws.httpapi",
"request_id": "123",
"resource_names": "GET /hello",
@@ -2270,7 +2270,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"connection_id": "ZLr9QeNLmjQCIZA=",
"endpoint": "$connect",
"event_type": "CONNECT",
- "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com$connect",
+ "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.com$connect",
"message_direction": "IN",
"operation_name": "aws.apigateway.websocket",
"request_id": "123",
@@ -2294,7 +2294,7 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None):
"connection_id": "ZLwtceO1mjQCI8Q=",
"endpoint": "main",
"event_type": "MESSAGE",
- "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.commain",
+ "http.url": "https://amddr1rix9.execute-api.eu-west-1.amazonaws.commain",
"message_direction": "IN",
"operation_name": "aws.apigateway.websocket",
"request_id": "123",
diff --git a/tests/test_trigger.py b/tests/test_trigger.py
index 9cb088f1..c12e8f5c 100644
--- a/tests/test_trigger.py
+++ b/tests/test_trigger.py
@@ -256,6 +256,30 @@ def test_event_source_unsupported(self):
self.assertEqual(event_source.to_string(), "unknown")
self.assertEqual(event_source_arn, None)
+ def test_event_source_with_non_dict_request_context(self):
+ # Test with requestContext as a string instead of a dict
+ event = {"requestContext": "not_a_dict"}
+ event_source = parse_event_source(event)
+ # Should still return a valid event source (unknown in this case)
+ self.assertEqual(event_source.to_string(), "unknown")
+
+ def test_event_source_with_invalid_domain_name(self):
+ # Test with domainName that isn't a string
+ event = {"requestContext": {"stage": "prod", "domainName": 12345}}
+ event_source = parse_event_source(event)
+ # Should detect as API Gateway since stage is present
+ self.assertEqual(event_source.to_string(), "api-gateway")
+
+ def test_detect_lambda_function_url_domain_with_invalid_input(self):
+ from datadog_lambda.trigger import detect_lambda_function_url_domain
+
+ # Test with non-string input
+ self.assertFalse(detect_lambda_function_url_domain(None))
+ self.assertFalse(detect_lambda_function_url_domain(12345))
+ self.assertFalse(detect_lambda_function_url_domain({"not": "a-string"}))
+ # Test with string that would normally cause an exception when split
+ self.assertFalse(detect_lambda_function_url_domain(""))
+
class GetTriggerTags(unittest.TestCase):
def test_extract_trigger_tags_api_gateway(self):
@@ -270,7 +294,7 @@ def test_extract_trigger_tags_api_gateway(self):
{
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/1234567890/stages/prod",
- "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/prod/path/to/resource",
"http.method": "POST",
"http.route": "/{proxy+}",
@@ -289,7 +313,7 @@ def test_extract_trigger_tags_api_gateway_non_proxy(self):
{
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/lgxbo6a518/stages/dev",
- "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://lgxbo6a518.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/dev/http/get",
"http.method": "GET",
"http.route": "/http/get",
@@ -308,7 +332,7 @@ def test_extract_trigger_tags_api_gateway_websocket_connect(self):
{
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev",
- "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com",
},
)
@@ -324,7 +348,7 @@ def test_extract_trigger_tags_api_gateway_websocket_default(self):
{
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev",
- "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com",
},
)
@@ -340,7 +364,7 @@ def test_extract_trigger_tags_api_gateway_websocket_disconnect(self):
{
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/p62c47itsb/stages/dev",
- "http.url": "p62c47itsb.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://p62c47itsb.execute-api.eu-west-1.amazonaws.com",
},
)
@@ -356,7 +380,7 @@ def test_extract_trigger_tags_api_gateway_http_api(self):
{
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/x02yirxc7a/stages/$default",
- "http.url": "x02yirxc7a.execute-api.eu-west-1.amazonaws.com",
+ "http.url": "https://x02yirxc7a.execute-api.eu-west-1.amazonaws.com",
"http.url_details.path": "/httpapi/get",
"http.method": "GET",
"http.route": "/httpapi/get",
@@ -530,6 +554,47 @@ def test_extract_trigger_tags_list_type_event(self):
tags = extract_trigger_tags(event, ctx)
self.assertEqual(tags, {})
+ def test_extract_http_tags_with_invalid_request_context(self):
+ from datadog_lambda.trigger import extract_http_tags
+
+ # Test with requestContext as a string instead of a dict
+ event = {"requestContext": "not_a_dict", "path": "/test", "httpMethod": "GET"}
+ http_tags = extract_http_tags(event)
+ # Should still extract valid tags from the event
+ self.assertEqual(
+ http_tags, {"http.url_details.path": "/test", "http.method": "GET"}
+ )
+
+ def test_extract_http_tags_with_invalid_apigateway_http(self):
+ from datadog_lambda.trigger import extract_http_tags
+
+ # Test with http in requestContext that's not a dict
+ event = {
+ "requestContext": {"stage": "prod", "http": "not_a_dict"},
+ "version": "2.0",
+ }
+ http_tags = extract_http_tags(event)
+ # Should not raise an exception
+ self.assertEqual(http_tags, {})
+
+ def test_extract_http_tags_with_invalid_headers(self):
+ from datadog_lambda.trigger import extract_http_tags
+
+ # Test with headers that's not a dict
+ event = {"headers": "not_a_dict"}
+ http_tags = extract_http_tags(event)
+ # Should not raise an exception
+ self.assertEqual(http_tags, {})
+
+ def test_extract_http_tags_with_invalid_route(self):
+ from datadog_lambda.trigger import extract_http_tags
+
+ # Test with routeKey that would cause a split error
+ event = {"routeKey": 12345} # Not a string
+ http_tags = extract_http_tags(event)
+ # Should not raise an exception
+ self.assertEqual(http_tags, {})
+
class ExtractHTTPStatusCodeTag(unittest.TestCase):
def test_extract_http_status_code_tag_from_response_dict(self):
diff --git a/tests/test_wrapper.py b/tests/test_wrapper.py
index 4b243036..f482fa3d 100644
--- a/tests/test_wrapper.py
+++ b/tests/test_wrapper.py
@@ -76,6 +76,10 @@ def setUp(self):
self.mock_dd_lambda_layer_tag = patcher.start()
self.addCleanup(patcher.stop)
+ patcher = patch("datadog_lambda.wrapper.set_dsm_context")
+ self.mock_set_dsm_context = patcher.start()
+ self.addCleanup(patcher.stop)
+
def test_datadog_lambda_wrapper(self):
wrapper.dd_tracing_enabled = False
@@ -283,7 +287,7 @@ def test_5xx_sends_errors_metric_and_set_tags(self, mock_extract_trigger_tags):
mock_extract_trigger_tags.return_value = {
"function_trigger.event_source": "api-gateway",
"function_trigger.event_source_arn": "arn:aws:apigateway:us-west-1::/restapis/1234567890/stages/prod",
- "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com",
+ "http.url": "https://70ixmpl4fl.execute-api.us-east-2.amazonaws.com",
"http.url_details.path": "/prod/path/to/resource",
"http.method": "GET",
}
@@ -563,6 +567,62 @@ def return_type_test(event, context):
self.assertEqual(result, test_result)
self.assertFalse(MockPrintExc.called)
+ def test_set_dsm_context_called_when_DSM_and_tracing_enabled(self):
+ os.environ["DD_DATA_STREAMS_ENABLED"] = "true"
+ wrapper.dd_tracing_enabled = True
+
+ @wrapper.datadog_lambda_wrapper
+ def lambda_handler(event, context):
+ return "ok"
+
+ result = lambda_handler({}, get_mock_context())
+ self.assertEqual(result, "ok")
+ self.mock_set_dsm_context.assert_called_once()
+
+ del os.environ["DD_DATA_STREAMS_ENABLED"]
+
+ def test_set_dsm_context_not_called_when_only_DSM_enabled(self):
+ os.environ["DD_DATA_STREAMS_ENABLED"] = "true"
+ wrapper.dd_tracing_enabled = False
+
+ @wrapper.datadog_lambda_wrapper
+ def lambda_handler(event, context):
+ return "ok"
+
+ result = lambda_handler({}, get_mock_context())
+ self.assertEqual(result, "ok")
+ self.mock_set_dsm_context.assert_not_called()
+
+ del os.environ["DD_DATA_STREAMS_ENABLED"]
+
+ def test_set_dsm_context_not_called_when_only_tracing_enabled(self):
+ os.environ["DD_DATA_STREAMS_ENABLED"] = "false"
+ wrapper.dd_tracing_enabled = True
+
+ @wrapper.datadog_lambda_wrapper
+ def lambda_handler(event, context):
+ return "ok"
+
+ result = lambda_handler({}, get_mock_context())
+ self.assertEqual(result, "ok")
+ self.mock_set_dsm_context.assert_not_called()
+
+ del os.environ["DD_DATA_STREAMS_ENABLED"]
+
+ def test_set_dsm_context_not_called_when_tracing_and_DSM_disabled(self):
+ os.environ["DD_DATA_STREAMS_ENABLED"] = "false"
+ wrapper.dd_tracing_enabled = False
+
+ @wrapper.datadog_lambda_wrapper
+ def lambda_handler(event, context):
+ return "ok"
+
+ result = lambda_handler({}, get_mock_context())
+ self.assertEqual(result, "ok")
+ self.mock_set_dsm_context.assert_not_called()
+
+ del os.environ["DD_DATA_STREAMS_ENABLED"]
+
class TestLambdaDecoratorSettings(unittest.TestCase):
def test_some_envs_should_depend_on_dd_tracing_enabled(self):