diff --git a/CHANGELOG.md b/CHANGELOG.md index 74105aa672..eb4f59e119 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.12.0rc1-0.31b0...HEAD) ### Fixed +- Adding escape call to fix [auto-instrumentation not producing spans on Windows](https://github.com/open-telemetry/opentelemetry-python/issues/2703). + ([#1100](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1100)) - `opentelemetry-instrumentation-grpc` narrow protobuf dependency to exclude protobuf >= 4 ([1109](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1109)) - cleanup type hints for textmap `Getter` and `Setter` classes diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py index 25ee3fe048..9504e359af 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py @@ -15,7 +15,6 @@ from logging import getLogger from os import environ from os.path import abspath, dirname, pathsep -from re import sub from pkg_resources import iter_entry_points @@ -26,6 +25,7 @@ from opentelemetry.instrumentation.environment_variables import ( OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, ) +from opentelemetry.instrumentation.utils import _python_path_without_directory from opentelemetry.instrumentation.version import __version__ logger = getLogger(__name__) @@ -111,10 +111,8 @@ def _load_configurators(): def initialize(): # prevents auto-instrumentation of subprocesses if code execs another python process - environ["PYTHONPATH"] = sub( - rf"{dirname(abspath(__file__))}{pathsep}?", - "", - environ["PYTHONPATH"], + environ["PYTHONPATH"] = _python_path_without_directory( + environ["PYTHONPATH"], dirname(abspath(__file__)), pathsep ) try: diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py index 56f174d758..fea7608388 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py @@ -13,6 +13,7 @@ # limitations under the License. import urllib.parse +from re import escape, sub from typing import Dict, Sequence from wrapt import ObjectProxy @@ -163,3 +164,11 @@ def _generate_opentelemetry_traceparent(span: Span) -> str: _traceparent = _version + "-" + _trace_id + "-" + _span_id + "-" + _flags meta.update({"traceparent": _traceparent}) return meta + + +def _python_path_without_directory(python_path, directory, path_separator): + return sub( + rf"{escape(directory)}{path_separator}(?!$)", + "", + python_path, + ) diff --git a/opentelemetry-instrumentation/tests/test_utils.py b/opentelemetry-instrumentation/tests/test_utils.py index ac8b9268c3..b7c9ecdc6e 100644 --- a/opentelemetry-instrumentation/tests/test_utils.py +++ b/opentelemetry-instrumentation/tests/test_utils.py @@ -14,7 +14,10 @@ from http import HTTPStatus -from opentelemetry.instrumentation.utils import http_status_to_status_code +from opentelemetry.instrumentation.utils import ( + _python_path_without_directory, + http_status_to_status_code, +) from opentelemetry.test.test_base import TestBase from opentelemetry.trace import StatusCode @@ -111,3 +114,41 @@ def test_http_status_to_status_code_server(self): int(status_code), server_span=True ) self.assertEqual(actual, expected, status_code) + + def test_remove_current_directory_from_python_path_windows(self): + directory = r"c:\users\Trayvon Martin\workplace\opentelemetry-python-contrib\opentelemetry-instrumentation\src\opentelemetry\instrumentation\auto_instrumentation" + path_separator = r";" + python_path = r"c:\users\Trayvon Martin\workplace\opentelemetry-python-contrib\opentelemetry-instrumentation\src\opentelemetry\instrumentation\auto_instrumentation;C:\Users\trayvonmartin\workplace" + actual_python_path = _python_path_without_directory( + python_path, directory, path_separator + ) + expected_python_path = r"C:\Users\trayvonmartin\workplace" + self.assertEqual(actual_python_path, expected_python_path) + + def test_remove_current_directory_from_python_path_linux(self): + directory = r"/home/georgefloyd/workplace/opentelemetry-python-contrib/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation" + path_separator = r":" + python_path = r"/home/georgefloyd/workplace/opentelemetry-python-contrib/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation:/home/georgefloyd/workplace" + actual_python_path = _python_path_without_directory( + python_path, directory, path_separator + ) + expected_python_path = r"/home/georgefloyd/workplace" + self.assertEqual(actual_python_path, expected_python_path) + + def test_remove_current_directory_from_python_path_windows_only_path(self): + directory = r"c:\users\Charleena Lyles\workplace\opentelemetry-python-contrib\opentelemetry-instrumentation\src\opentelemetry\instrumentation\auto_instrumentation" + path_separator = r";" + python_path = r"c:\users\Charleena Lyles\workplace\opentelemetry-python-contrib\opentelemetry-instrumentation\src\opentelemetry\instrumentation\auto_instrumentation" + actual_python_path = _python_path_without_directory( + python_path, directory, path_separator + ) + self.assertEqual(actual_python_path, python_path) + + def test_remove_current_directory_from_python_path_linux_only_path(self): + directory = r"/home/SandraBland/workplace/opentelemetry-python-contrib/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation" + path_separator = r":" + python_path = r"/home/SandraBland/workplace/opentelemetry-python-contrib/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation" + actual_python_path = _python_path_without_directory( + python_path, directory, path_separator + ) + self.assertEqual(actual_python_path, python_path)