From 5942f7d6822d50d235f0fabc19ff52d4672d7a5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 04:48:56 +0000 Subject: [PATCH 1/8] Bump idna from 3.6 to 3.7 in /sample-apps/flask Bumps [idna](https://github.com/kjd/idna) from 3.6 to 3.7. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) - [Commits](https://github.com/kjd/idna/compare/v3.6...v3.7) --- updated-dependencies: - dependency-name: idna dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- sample-apps/flask/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-apps/flask/requirements.txt b/sample-apps/flask/requirements.txt index 06765afd..0d87e23f 100644 --- a/sample-apps/flask/requirements.txt +++ b/sample-apps/flask/requirements.txt @@ -2,7 +2,7 @@ boto3==1.34.26 certifi==2023.11.17 chardet==5.2.0 Flask==2.3.3 -idna==3.6 +idna==3.7 requests==2.31.0 urllib3==1.26.18 Werkzeug==3.0.1 From a6a3e86a8f1049e09a44851275ccf9c4ef185940 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Mon, 22 Apr 2024 09:14:43 -0700 Subject: [PATCH 2/8] Fix end_time param type docstring (#426) --- aws_xray_sdk/core/context.py | 4 ++-- aws_xray_sdk/core/models/entity.py | 2 +- aws_xray_sdk/core/models/subsegment.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aws_xray_sdk/core/context.py b/aws_xray_sdk/core/context.py index 63e994de..553c85a2 100644 --- a/aws_xray_sdk/core/context.py +++ b/aws_xray_sdk/core/context.py @@ -44,7 +44,7 @@ def end_segment(self, end_time=None): """ End the current active segment. - :param int end_time: epoch in seconds. If not specified the current + :param float end_time: epoch in seconds. If not specified the current system time will be used. """ entity = self.get_trace_entity() @@ -75,7 +75,7 @@ def end_subsegment(self, end_time=None): End the current active segment. Return False if there is no subsegment to end. - :param int end_time: epoch in seconds. If not specified the current + :param float end_time: epoch in seconds. If not specified the current system time will be used. """ subsegment = self.get_trace_entity() diff --git a/aws_xray_sdk/core/models/entity.py b/aws_xray_sdk/core/models/entity.py index a2150a5e..9a5d08e7 100644 --- a/aws_xray_sdk/core/models/entity.py +++ b/aws_xray_sdk/core/models/entity.py @@ -64,7 +64,7 @@ def close(self, end_time=None): Close the trace entity by setting `end_time` and flip the in progress flag to False. - :param int end_time: Epoch in seconds. If not specified + :param float end_time: Epoch in seconds. If not specified current time will be used. """ self._check_ended() diff --git a/aws_xray_sdk/core/models/subsegment.py b/aws_xray_sdk/core/models/subsegment.py index 3c4289e9..53f944de 100644 --- a/aws_xray_sdk/core/models/subsegment.py +++ b/aws_xray_sdk/core/models/subsegment.py @@ -133,7 +133,7 @@ def close(self, end_time=None): and flip the in progress flag to False. Also decrement parent segment's ref counter by 1. - :param int end_time: Epoch in seconds. If not specified + :param float end_time: Epoch in seconds. If not specified current time will be used. """ super().close(end_time) From 99035a854d19b7519812a96bf3a0a8c32bd8aa15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 19:20:31 +0000 Subject: [PATCH 3/8] Bump werkzeug from 3.0.1 to 3.0.3 in /sample-apps/flask Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.0.1 to 3.0.3. - [Release notes](https://github.com/pallets/werkzeug/releases) - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/werkzeug/compare/3.0.1...3.0.3) --- updated-dependencies: - dependency-name: werkzeug dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- sample-apps/flask/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-apps/flask/requirements.txt b/sample-apps/flask/requirements.txt index 06765afd..5dc5a474 100644 --- a/sample-apps/flask/requirements.txt +++ b/sample-apps/flask/requirements.txt @@ -5,7 +5,7 @@ Flask==2.3.3 idna==3.6 requests==2.31.0 urllib3==1.26.18 -Werkzeug==3.0.1 +Werkzeug==3.0.3 flask-sqlalchemy==2.5.1 SQLAlchemy==1.4 aws_xray_sdk==2.6.0 From 3be0c9bad4de8aed1f62b2e71d6ea54eeeadaa62 Mon Sep 17 00:00:00 2001 From: Mahad Janjua Date: Tue, 7 May 2024 14:15:46 -0700 Subject: [PATCH 4/8] [Lambda] Create dummy segment when trace header is incomplete This change makes it so that when the trace header is incomplete no new subsegments will be added. Customers can call the X-Ray SDK APIs without any output in this case. --- aws_xray_sdk/core/lambda_launcher.py | 32 +++++++++++++++++----------- tests/test_lambda_context.py | 9 ++++---- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/aws_xray_sdk/core/lambda_launcher.py b/aws_xray_sdk/core/lambda_launcher.py index adfb50eb..55d782b4 100644 --- a/aws_xray_sdk/core/lambda_launcher.py +++ b/aws_xray_sdk/core/lambda_launcher.py @@ -3,6 +3,7 @@ import threading from aws_xray_sdk import global_sdk_config +from .models.dummy_entities import DummySegment from .models.facade_segment import FacadeSegment from .models.trace_header import TraceHeader from .context import Context @@ -44,7 +45,7 @@ class LambdaContext(Context): """ Lambda service will generate a segment for each function invocation which cannot be mutated. The context doesn't keep any manually created segment - but instead every time ``get_trace_entity()`` gets called it refresh the facade + but instead every time ``get_trace_entity()`` gets called it refresh the segment based on environment variables set by Lambda worker. """ def __init__(self): @@ -65,12 +66,12 @@ def end_segment(self, end_time=None): def put_subsegment(self, subsegment): """ - Refresh the facade segment every time this function is invoked to prevent + Refresh the segment every time this function is invoked to prevent a new subsegment from being attached to a leaked segment/subsegment. """ current_entity = self.get_trace_entity() - if not self._is_subsegment(current_entity) and current_entity.initializing: + if not self._is_subsegment(current_entity) and (getattr(current_entity, 'initializing', None) or isinstance(current_entity, DummySegment)): if global_sdk_config.sdk_enabled(): log.warning("Subsegment %s discarded due to Lambda worker still initializing" % subsegment.name) return @@ -99,9 +100,9 @@ def get_trace_entity(self): def _refresh_context(self): """ - Get current facade segment. To prevent resource leaking in Lambda worker, + Get current segment. To prevent resource leaking in Lambda worker, every time there is segment present, we compare its trace id to current - environment variables. If it is different we create a new facade segment + environment variables. If it is different we create a new segment and clean up subsegments stored. """ header_str = os.getenv(LAMBDA_TRACE_HEADER_KEY) @@ -136,8 +137,8 @@ def handle_context_missing(self): def _initialize_context(self, trace_header): """ - Create a facade segment based on environment variables - set by AWS Lambda and initialize storage for subsegments. + Create a segment based on environment variables set by + AWS Lambda and initialize storage for subsegments. """ sampled = None if not global_sdk_config.sdk_enabled(): @@ -148,12 +149,17 @@ def _initialize_context(self, trace_header): elif trace_header.sampled == 1: sampled = True - segment = FacadeSegment( - name='facade', - traceid=trace_header.root, - entityid=trace_header.parent, - sampled=sampled, - ) + segment = None + if not trace_header.root or not trace_header.parent or trace_header.sampled is None: + segment = DummySegment() + log.debug("Creating NoOp/Dummy parent segment") + else: + segment = FacadeSegment( + name='facade', + traceid=trace_header.root, + entityid=trace_header.parent, + sampled=sampled, + ) segment.save_origin_trace_header(trace_header) setattr(self._local, 'segment', segment) setattr(self._local, 'entities', []) diff --git a/tests/test_lambda_context.py b/tests/test_lambda_context.py index 92483b04..09e08873 100644 --- a/tests/test_lambda_context.py +++ b/tests/test_lambda_context.py @@ -67,18 +67,19 @@ def test_disable(): def test_non_initialized(): - # Context that hasn't been initialized by lambda container should not add subsegments to the facade segment. + # Context that hasn't been initialized by lambda container should not add subsegments to the dummy segment. temp_header_var = os.environ[lambda_launcher.LAMBDA_TRACE_HEADER_KEY] del os.environ[lambda_launcher.LAMBDA_TRACE_HEADER_KEY] temp_context = lambda_launcher.LambdaContext() - facade_segment = temp_context.get_trace_entity() - subsegment = Subsegment("TestSubsegment", "local", facade_segment) + dummy_segment = temp_context.get_trace_entity() + subsegment = Subsegment("TestSubsegment", "local", dummy_segment) temp_context.put_subsegment(subsegment) - assert temp_context.get_trace_entity() == facade_segment + assert temp_context.get_trace_entity() == dummy_segment # "Lambda" container added metadata now. Should see subsegment now. + # The following put_segment call will overwrite the dummy segment in the context with an intialized facade segment that accepts a subsegment. os.environ[lambda_launcher.LAMBDA_TRACE_HEADER_KEY] = temp_header_var temp_context.put_subsegment(subsegment) From d174f8d1ffebcf1e9775a22e310735bb4b59f6cf Mon Sep 17 00:00:00 2001 From: Mahad Janjua Date: Wed, 8 May 2024 10:20:39 -0700 Subject: [PATCH 5/8] [Lambda] Add unit test for lambda passthrough trace header case --- tests/test_lambda_context.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_lambda_context.py b/tests/test_lambda_context.py index 09e08873..b7299c72 100644 --- a/tests/test_lambda_context.py +++ b/tests/test_lambda_context.py @@ -3,6 +3,7 @@ from aws_xray_sdk import global_sdk_config import pytest from aws_xray_sdk.core import lambda_launcher +from aws_xray_sdk.core.models.dummy_entities import DummySegment from aws_xray_sdk.core.models.subsegment import Subsegment @@ -85,6 +86,30 @@ def test_non_initialized(): assert temp_context.get_trace_entity() == subsegment +def test_lambda_passthrough(): + # Hold previous environment value + temp_header_var = os.environ[lambda_launcher.LAMBDA_TRACE_HEADER_KEY] + del os.environ[lambda_launcher.LAMBDA_TRACE_HEADER_KEY] + + # Set header to lambda passthrough style header + os.environ[lambda_launcher.LAMBDA_TRACE_HEADER_KEY] = "Root=%s;Lineage=10:1234abcd:3" % TRACE_ID + + temp_context = lambda_launcher.LambdaContext() + dummy_segment = temp_context.get_trace_entity() + subsegment = Subsegment("TestSubsegment", "local", dummy_segment) + temp_context.put_subsegment(subsegment) + + # Resulting entity is not the same dummy segment, so simply check that it is a dummy segment + assert isinstance(temp_context.get_trace_entity(), DummySegment) + + # Reset header value and ensure behaviour returns to normal + del os.environ[lambda_launcher.LAMBDA_TRACE_HEADER_KEY] + os.environ[lambda_launcher.LAMBDA_TRACE_HEADER_KEY] = temp_header_var + temp_context.put_subsegment(subsegment) + + assert temp_context.get_trace_entity() == subsegment + + def test_set_trace_entity(): segment = context.get_trace_entity() From 07ac6f832637100e0140ca2cd28f0d7da4a4c2e6 Mon Sep 17 00:00:00 2001 From: jjllee Date: Mon, 13 May 2024 13:50:43 -0700 Subject: [PATCH 6/8] update pytest-asyncio to >= 0.21.2 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index c5d7875e..7dfc1b9b 100644 --- a/tox.ini +++ b/tox.ini @@ -56,7 +56,7 @@ deps = wrapt ; Python 3.5+ only deps - py{37,38,39,310,311,312}: pytest-asyncio == 0.21.1 + py{37,38,39,310,311,312}: pytest-asyncio == 0.21.2 ; For pkg_resources py{37,38,39,310,311,312}: setuptools From 35826073902a6b4b12d36eb7e2854d32aa6b29b0 Mon Sep 17 00:00:00 2001 From: Mahad Janjua <134644284+majanjua-amzn@users.noreply.github.com> Date: Wed, 15 May 2024 09:43:18 -0700 Subject: [PATCH 7/8] [Lambda] Fix logging to only happen inside lambda function --- aws_xray_sdk/core/lambda_launcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_xray_sdk/core/lambda_launcher.py b/aws_xray_sdk/core/lambda_launcher.py index 55d782b4..ef6f8986 100644 --- a/aws_xray_sdk/core/lambda_launcher.py +++ b/aws_xray_sdk/core/lambda_launcher.py @@ -72,7 +72,7 @@ def put_subsegment(self, subsegment): current_entity = self.get_trace_entity() if not self._is_subsegment(current_entity) and (getattr(current_entity, 'initializing', None) or isinstance(current_entity, DummySegment)): - if global_sdk_config.sdk_enabled(): + if global_sdk_config.sdk_enabled() and not os.getenv(LAMBDA_TRACE_HEADER_KEY): log.warning("Subsegment %s discarded due to Lambda worker still initializing" % subsegment.name) return From a3ff59a9cadeefb6fa6469e9151c0080dc3ba129 Mon Sep 17 00:00:00 2001 From: jjllee Date: Fri, 17 May 2024 13:47:33 -0700 Subject: [PATCH 8/8] Release commit for v2.13.1 --- CHANGELOG.rst | 8 ++++++++ aws_xray_sdk/version.py | 2 +- docs/conf.py | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c6457126..36c2d4a5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,14 @@ CHANGELOG Unreleased ========== +2.13.1 +========== +* improvement: Bump idna from 3.6 to 3.7 in /sample-apps/flask `https://github.com/aws/aws-xray-sdk-python/pull/425` +* bugfix: Fix end_time param type docstring from int to float `https://github.com/aws/aws-xray-sdk-python/pull/426` +* improvement: Bump werkzeug from 3.0.1 to 3.0.3 in /sample-apps/flask `https://github.com/aws/aws-xray-sdk-python/pull/428` +* improvement: [LambdaContext] Create dummy segment when trace header is incomplete `https://github.com/aws/aws-xray-sdk-python/pull/429` +* bugfix: [LambdaContext] Fix logging to only happen inside lambda function `https://github.com/aws/aws-xray-sdk-python/pull/431` + 2.13.0 ========== * bugfix: Fix passing multiple values in testenv.passenv in tox.ini `https://github.com/aws/aws-xray-sdk-python/pull/399` diff --git a/aws_xray_sdk/version.py b/aws_xray_sdk/version.py index 8ef56164..19502509 100644 --- a/aws_xray_sdk/version.py +++ b/aws_xray_sdk/version.py @@ -1 +1 @@ -VERSION = '2.13.0' +VERSION = '2.13.1' diff --git a/docs/conf.py b/docs/conf.py index cff4885e..52b40c41 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -62,9 +62,9 @@ # built documents. # # The short X.Y version. -version = u'2.13.0' +version = u'2.13.1' # The full version, including alpha/beta/rc tags. -release = u'2.13.0' +release = u'2.13.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages.