From 81e38e4b10234e75e87d9b35beef94f50026033b Mon Sep 17 00:00:00 2001 From: Hang Cheng Date: Thu, 9 Feb 2023 10:40:55 -0800 Subject: [PATCH 1/3] Fix issue with Flask instrumentation when a request spawn children threads and copie the request context --- CHANGELOG.md | 2 +- .../opentelemetry/instrumentation/flask/__init__.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba513aebfa..5691c71175 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1618](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1618)) ### Fixed - +- Fix Flask instrumentation to only close the span if it was created by the same thread. `ValueError: generator already executing` ([#1654](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1654)) - Fix TortoiseORM instrumentation `AttributeError: type object 'Config' has no attribute 'title'` ([#1575](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1575)) - Fix SQLAlchemy uninstrumentation diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py index 922c5e0b41..fd3c40aab3 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -238,8 +238,8 @@ def response_hook(span: Span, status: str, response_headers: List): API --- """ - from logging import getLogger +from threading import get_ident from time import time_ns from timeit import default_timer from typing import Collection @@ -265,6 +265,7 @@ def response_hook(span: Span, status: str, response_headers: List): _ENVIRON_STARTTIME_KEY = "opentelemetry-flask.starttime_key" _ENVIRON_SPAN_KEY = "opentelemetry-flask.span_key" _ENVIRON_ACTIVATION_KEY = "opentelemetry-flask.activation_key" +_ENVIRON_THREAD_ID_KEY = "opentelemetry-flask.thread_id_key" _ENVIRON_TOKEN = "opentelemetry-flask.token" _excluded_urls_from_env = get_excluded_urls("FLASK") @@ -398,6 +399,7 @@ def _before_request(): activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 flask_request_environ[_ENVIRON_ACTIVATION_KEY] = activation + flask_request_environ[_ENVIRON_THREAD_ID_KEY] = get_ident() flask_request_environ[_ENVIRON_SPAN_KEY] = span flask_request_environ[_ENVIRON_TOKEN] = token @@ -437,10 +439,17 @@ def _teardown_request(exc): return activation = flask.request.environ.get(_ENVIRON_ACTIVATION_KEY) - if not activation: + thread_id = flask.request.environ.get(_ENVIRON_THREAD_ID_KEY) + if not activation or thread_id != get_ident(): # This request didn't start a span, maybe because it was created in # a way that doesn't run `before_request`, like when it is created # with `app.test_request_context`. + # + # Similarly, check the thread_id against the current thread to ensure + # tear down only happens on the original thread. This situation can + # arise if the original thread handling the request spawn children + # threads and then uses something like copy_current_request_context + # to copy the request context. return if exc is None: activation.__exit__(None, None, None) From 4d51a10b239f30c3a1142a24046cf224b227701b Mon Sep 17 00:00:00 2001 From: hangonlyra <46975104+hangonlyra@users.noreply.github.com> Date: Mon, 13 Feb 2023 10:59:02 -0800 Subject: [PATCH 2/3] Update CHANGELOG.md Co-authored-by: Srikanth Chekuri --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a4b6d034c..1b62dc6f6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1618](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1618)) ### Fixed -- Fix Flask instrumentation to only close the span if it was created by the same thread. `ValueError: generator already executing` ([#1654](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1654)) + +- Fix Flask instrumentation to only close the span if it was created by the same thread. `ValueError: generator already executing` + ([#1654](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1654)) - Fix TortoiseORM instrumentation `AttributeError: type object 'Config' has no attribute 'title'` ([#1575](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1575)) - Fix SQLAlchemy uninstrumentation From 631828aa2856cac5a26c85c65f9c7ebff982e3ac Mon Sep 17 00:00:00 2001 From: hangonlyra <46975104+hangonlyra@users.noreply.github.com> Date: Wed, 15 Feb 2023 08:58:32 -0800 Subject: [PATCH 3/3] Update CHANGELOG.md Co-authored-by: Aaron Abbott --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b873a20d84..b83f1e33f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Fix Flask instrumentation to only close the span if it was created by the same thread. `ValueError: generator already executing` +- Fix Flask instrumentation to only close the span if it was created by the same thread. ([#1654](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1654)) - Fix TortoiseORM instrumentation `AttributeError: type object 'Config' has no attribute 'title'` ([#1575](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1575))